diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/classlist.cpp | 14 | ||||
-rw-r--r-- | src/commentcnv.l | 1 | ||||
-rw-r--r-- | src/commentscan.h | 29 | ||||
-rw-r--r-- | src/commentscan.l | 557 | ||||
-rw-r--r-- | src/config.l | 4 | ||||
-rw-r--r-- | src/doctokenizer.l | 8 | ||||
-rw-r--r-- | src/doxygen.cpp | 9 | ||||
-rw-r--r-- | src/memberdef.cpp | 8 | ||||
-rw-r--r-- | src/outputgen.h | 2 | ||||
-rw-r--r-- | src/parserintf.h | 11 | ||||
-rw-r--r-- | src/pycode.l | 350 | ||||
-rw-r--r-- | src/pyscanner.h | 2 | ||||
-rw-r--r-- | src/pyscanner.l | 1158 | ||||
-rw-r--r-- | src/scanner.h | 2 | ||||
-rw-r--r-- | src/scanner.l | 381 | ||||
-rw-r--r-- | src/search.php | 2 | ||||
-rw-r--r-- | src/search_php.h | 2 | ||||
-rw-r--r-- | src/translator_adapter.h | 1 | ||||
-rw-r--r-- | src/translator_en.h | 4 | ||||
-rw-r--r-- | src/util.cpp | 6 | ||||
-rw-r--r-- | src/util.h | 2 |
21 files changed, 1580 insertions, 973 deletions
diff --git a/src/classlist.cpp b/src/classlist.cpp index fa93a73..b0a1b7f 100644 --- a/src/classlist.cpp +++ b/src/classlist.cpp @@ -34,15 +34,17 @@ static int compItems(void *item1,void *item2) { ClassDef *c1=(ClassDef *)item1; ClassDef *c2=(ClassDef *)item2; - int p1=0,p2=0; static bool b = Config_getBool("SORT_BY_SCOPE_NAME"); - if (!b) + if (b) { - p1=getPrefixIndex(c1->className()); - p2=getPrefixIndex(c2->className()); + return stricmp(c1->qualifiedName(), + c2->qualifiedName()); + } + else + { + return stricmp(c1->className(), + c2->className()); } - return stricmp(c1->className().data()+p1, - c2->className().data()+p2); } int ClassList::compareItems(GCI item1, GCI item2) diff --git a/src/commentcnv.l b/src/commentcnv.l index c29e731..9e7f8a4 100644 --- a/src/commentcnv.l +++ b/src/commentcnv.l @@ -542,6 +542,7 @@ void convertCppComments(BufStr *inBuf,BufStr *outBuf,const char *fileName) } } + //---------------------------------------------------------------------------- #if !defined(YY_FLEX_SUBMINOR_VERSION) extern "C" { // some bogus code to keep the compiler happy diff --git a/src/commentscan.h b/src/commentscan.h index 9d7fe7b..363dda2 100644 --- a/src/commentscan.h +++ b/src/commentscan.h @@ -21,14 +21,25 @@ class ParserInterface; -bool parseCommentBlock(/* in */ ParserInterface *parser, - /* in,out */ Entry *curEntry, - /* in */ const QCString &comment, - /* in */ const QCString &fileName, - /* in */ int lineNr, - /* in */ bool isBrief, - /* in */ bool isJavaDocStyle, - /* in,out */ Protection &prot - ); +int parseCommentBlock(/* in */ ParserInterface *parser, + /* in */ Entry *curEntry, + /* in */ const QCString &comment, + /* in */ const QCString &fileName, + /* in */ int lineNr, + /* in */ bool isBrief, + /* in */ bool isJavaDocStyle, + /* in,out */ Protection &prot, + /* in,out */ int &position, + /* out */ bool &newEntryNeeded + ); + +void groupEnterFile(const char *file,int line); +void groupLeaveFile(const char *file,int line); +void groupLeaveCompound(const char *file,int line,const char *name); +void groupEnterCompound(const char *file,int line,const char *name); +void openGroup(Entry *e,const char *file,int line); +void closeGroup(Entry *,const char *file,int line); +void initGroupInfo(Entry *e); + #endif diff --git a/src/commentscan.l b/src/commentscan.l index ff6e603..a44caa7 100644 --- a/src/commentscan.l +++ b/src/commentscan.l @@ -46,67 +46,67 @@ #include "parserintf.h" // forward declarations -static void handleBrief(const QCString &); -static void handleFn(const QCString &); -static void handleDef(const QCString &); -static void handleOverload(const QCString &); -static void handleEnum(const QCString &); -static void handleDefGroup(const QCString &); -static void handleAddToGroup(const QCString &); -static void handleWeakGroup(const QCString &); -static void handleNamespace(const QCString &); -static void handlePackage(const QCString &); -static void handleClass(const QCString &); -static void handleProtocol(const QCString &); -static void handleCategory(const QCString &); -static void handleUnion(const QCString &); -static void handleStruct(const QCString &); -static void handleInterface(const QCString &); -static void handleIdlException(const QCString &); -static void handlePage(const QCString &); -static void handleMainpage(const QCString &); -static void handleFile(const QCString &); -static void handleDir(const QCString &); -static void handleExample(const QCString &); -static void handleDetails(const QCString &); -static void handleName(const QCString &); -static void handleTodo(const QCString &); -static void handleTest(const QCString &); -static void handleBug(const QCString &); -static void handleSubpage(const QCString &s); -static void handleDeprecated(const QCString &); -static void handleXRefItem(const QCString &); -static void handleRelated(const QCString &); -static void handleRelatedAlso(const QCString &); -static void handleRefItem(const QCString &); -static void handleSection(const QCString &); -static void handleAnchor(const QCString &); -static void handleFormatBlock(const QCString &); -static void handleAddIndex(const QCString &); -static void handleIf(const QCString &); -static void handleIfNot(const QCString &); -static void handleElseIf(const QCString &); -static void handleElse(const QCString &); -static void handleEndIf(const QCString &); -static void handleIngroup(const QCString &); -static void handleNoSubGrouping(const QCString &); -static void handleShowInitializer(const QCString &); -static void handleHideInitializer(const QCString &); -static void handleCallgraph(const QCString &); -static void handleInternal(const QCString &); -static void handleLineBr(const QCString &); -static void handleStatic(const QCString &); -static void handlePure(const QCString &); -static void handlePrivate(const QCString &); -static void handlePrivateSection(const QCString &); -static void handleProtected(const QCString &); -static void handleProtectedSection(const QCString &); -static void handlePublic(const QCString &s); -static void handlePublicSection(const QCString &s); -static void handleInherit(const QCString &); - - -typedef void (*DocCmdFunc)(const QCString &name); +static bool handleBrief(const QCString &); +static bool handleFn(const QCString &); +static bool handleDef(const QCString &); +static bool handleOverload(const QCString &); +static bool handleEnum(const QCString &); +static bool handleDefGroup(const QCString &); +static bool handleAddToGroup(const QCString &); +static bool handleWeakGroup(const QCString &); +static bool handleNamespace(const QCString &); +static bool handlePackage(const QCString &); +static bool handleClass(const QCString &); +static bool handleProtocol(const QCString &); +static bool handleCategory(const QCString &); +static bool handleUnion(const QCString &); +static bool handleStruct(const QCString &); +static bool handleInterface(const QCString &); +static bool handleIdlException(const QCString &); +static bool handlePage(const QCString &); +static bool handleMainpage(const QCString &); +static bool handleFile(const QCString &); +static bool handleDir(const QCString &); +static bool handleExample(const QCString &); +static bool handleDetails(const QCString &); +static bool handleName(const QCString &); +static bool handleTodo(const QCString &); +static bool handleTest(const QCString &); +static bool handleBug(const QCString &); +static bool handleSubpage(const QCString &s); +static bool handleDeprecated(const QCString &); +static bool handleXRefItem(const QCString &); +static bool handleRelated(const QCString &); +static bool handleRelatedAlso(const QCString &); +static bool handleRefItem(const QCString &); +static bool handleSection(const QCString &); +static bool handleAnchor(const QCString &); +static bool handleFormatBlock(const QCString &); +static bool handleAddIndex(const QCString &); +static bool handleIf(const QCString &); +static bool handleIfNot(const QCString &); +static bool handleElseIf(const QCString &); +static bool handleElse(const QCString &); +static bool handleEndIf(const QCString &); +static bool handleIngroup(const QCString &); +static bool handleNoSubGrouping(const QCString &); +static bool handleShowInitializer(const QCString &); +static bool handleHideInitializer(const QCString &); +static bool handleCallgraph(const QCString &); +static bool handleInternal(const QCString &); +static bool handleLineBr(const QCString &); +static bool handleStatic(const QCString &); +static bool handlePure(const QCString &); +static bool handlePrivate(const QCString &); +static bool handlePrivateSection(const QCString &); +static bool handleProtected(const QCString &); +static bool handleProtectedSection(const QCString &); +static bool handlePublic(const QCString &s); +static bool handlePublicSection(const QCString &s); +static bool handleInherit(const QCString &); + + +typedef bool (*DocCmdFunc)(const QCString &name); struct DocCmdMap { @@ -283,6 +283,9 @@ class GuardedSection bool m_parentVisible; }; +void openGroup(Entry *e,const char *file,int line); +void closeGroup(Entry *e,const char *file,int line); +static void groupAddDocs(Entry *e,const char *fileName); /* ----------------------------------------------------------------- * @@ -306,7 +309,6 @@ static XRefKind xrefKind; // kind of cross-reference command static XRefKind newXRefKind; // static GuardType guardType; // kind of guard for conditional section static bool enabledSectionFound; -static QCString nameHeader; // heading of the @name command static QCString functionProto; // function prototype static QStack<GuardedSection> guards; // tracks nested conditional sections (if,ifnot,..) static Entry* current = 0 ; // working entry @@ -328,6 +330,15 @@ static bool xrefAppendFlag; static bool inGroupParamFound; static int braceCount; static bool insidePre; +static bool parseMore; + +//----------------------------------------------------------------------------- + +static QStack<Grouping> g_autoGroupStack; +static int g_memberGroupId = DOX_NOGROUP; +static QCString g_memberGroupHeader; +static QCString g_memberGroupDocs; +static QCString g_memberGroupRelates; //----------------------------------------------------------------------------- @@ -335,7 +346,7 @@ static void initParser() { sectionLabel.resize(0); sectionTitle.resize(0); - nameHeader.resize(0); + g_memberGroupHeader.resize(0); } //----------------------------------------------------------------------------- @@ -369,16 +380,17 @@ static QCString getDocSectionName(int s) //----------------------------------------------------------------------------- -static void makeStructuralIndicator(Entry::Sections s) +static bool makeStructuralIndicator(Entry::Sections s) { if (!getDocSectionName(current->section).isEmpty()) { - warn(yyFileName,yyLineNr, - "Warning: found a structural command %s for a section already " - "marked with structural command %s. Ignoring the latter command.", - getDocSectionName(s).data(), - getDocSectionName(current->section).data() - ); + //warn(yyFileName,yyLineNr, + // "Warning: found a structural command %s for a section already " + // "marked with structural command %s. Ignoring the latter command.", + // getDocSectionName(s).data(), + // getDocSectionName(current->section).data() + // ); + return TRUE; } else { @@ -386,6 +398,7 @@ static void makeStructuralIndicator(Entry::Sections s) current->section = s; current->fileName = yyFileName; current->startLine = yyLineNr; + return FALSE; } } @@ -664,8 +677,11 @@ static inline void addOutput(char c) #undef YY_INPUT #define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size); +static int prevPosition=0; + static int yyread(char *buf,int max_size) { + prevPosition=inputPosition; int c=0; while( c < max_size && inputString[inputPosition] ) { @@ -818,8 +834,19 @@ MAILADR [a-z_A-Z0-9.+\-]+"@"[a-z_A-Z0-9\-]+("."[a-z_A-Z0-9\-]+)+[a-z_A-Z0-9\-] DocCmdFunc *funcPtr = DocCmdMapper::map(cmdName); if (funcPtr) // special action is required { - //printf("Special command '%s'\n",yytext); - (*funcPtr)(cmdName); + if ((*funcPtr)(cmdName)) + { + // implicit split of the comment block into two + // entries. Restart the next block at the start + // of this command. + parseMore=TRUE; + + // yuk, this is probably not very portable across lex implementations, + // but we need to know the position in the input buffer where this + // rule matched. + inputPosition=prevPosition + yy_bp - yy_current_buffer->yy_ch_buf; + yyterminate(); + } } else // command not relevant { @@ -852,11 +879,13 @@ MAILADR [a-z_A-Z0-9.+\-]+"@"[a-z_A-Z0-9\-]+("."[a-z_A-Z0-9\-]+)+[a-z_A-Z0-9\-] BEGIN(ReadFormulaLong); } <Comment>{CMD}"{" { // begin of a group - langParser->handleGroupStartCommand(nameHeader); + //langParser->handleGroupStartCommand(g_memberGroupHeader); + openGroup(current,yyFileName,yyLineNr); } <Comment>{CMD}"}" { // end of a group - langParser->handleGroupEndCommand(); - nameHeader.resize(0); + //langParser->handleGroupEndCommand(); + closeGroup(current,yyFileName,yyLineNr); + g_memberGroupHeader.resize(0); } <Comment>{CMD}[$@\\&~<>#%] { // escaped character addOutput(yytext); @@ -1154,6 +1183,11 @@ MAILADR [a-z_A-Z0-9.+\-]+"@"[a-z_A-Z0-9\-]+("."[a-z_A-Z0-9\-]+)+[a-z_A-Z0-9\-] /* --------- handle arguments of the file/dir/example command ------------ */ +<FileDocArg1>{DOCNL} { // no file name specfied + if (*yytext=='\n') yyLineNr++; + addOutput('\n'); + BEGIN( Comment ); + } <FileDocArg1>{FILE} { // first argument; name current->name = stripQuotes(yytext); BEGIN( Comment ); @@ -1161,11 +1195,6 @@ MAILADR [a-z_A-Z0-9.+\-]+"@"[a-z_A-Z0-9\-]+("."[a-z_A-Z0-9\-]+)+[a-z_A-Z0-9\-] <FileDocArg1>{LC} { yyLineNr++; addOutput('\n'); } -<FileDocArg1>{DOCNL} { // no file name specfied - if (*yytext=='\n') yyLineNr++; - addOutput('\n'); - BEGIN( Comment ); - } <FileDocArg1>. { // ignore other stuff } @@ -1542,10 +1571,10 @@ MAILADR [a-z_A-Z0-9.+\-]+"@"[a-z_A-Z0-9\-]+("."[a-z_A-Z0-9\-]+)+[a-z_A-Z0-9\-] <NameParam>{LC} { // line continuation yyLineNr++; addOutput('\n'); - nameHeader+=' '; + g_memberGroupHeader+=' '; } <NameParam>. { // ignore other stuff - nameHeader+=*yytext; + g_memberGroupHeader+=*yytext; current->name+=*yytext; } @@ -1679,218 +1708,251 @@ MAILADR [a-z_A-Z0-9.+\-]+"@"[a-z_A-Z0-9\-]+("."[a-z_A-Z0-9\-]+)+[a-z_A-Z0-9\-] //---------------------------------------------------------------------------- -static void handleBrief(const QCString &) +static bool handleBrief(const QCString &) { //printf("handleBrief\n"); setOutput(OutputBrief); + return FALSE; } -static void handleFn(const QCString &) +static bool handleFn(const QCString &) { - makeStructuralIndicator(Entry::MEMBERDOC_SEC); + bool stop=makeStructuralIndicator(Entry::MEMBERDOC_SEC); functionProto.resize(0); braceCount=0; BEGIN(FnParam); + return stop; } -static void handleDef(const QCString &) +static bool handleDef(const QCString &) { - makeStructuralIndicator(Entry::DEFINEDOC_SEC); + bool stop=makeStructuralIndicator(Entry::DEFINEDOC_SEC); functionProto.resize(0); BEGIN(FnParam); + return stop; } -static void handleOverload(const QCString &) +static bool handleOverload(const QCString &) { functionProto.resize(0); BEGIN(OverloadParam); + return FALSE; } -static void handleEnum(const QCString &) +static bool handleEnum(const QCString &) { - makeStructuralIndicator(Entry::ENUMDOC_SEC); + bool stop=makeStructuralIndicator(Entry::ENUMDOC_SEC); BEGIN(EnumDocArg1); + return stop; } -static void handleDefGroup(const QCString &) +static bool handleDefGroup(const QCString &) { - makeStructuralIndicator(Entry::GROUPDOC_SEC); + bool stop=makeStructuralIndicator(Entry::GROUPDOC_SEC); current->groupDocType = Entry::GROUPDOC_NORMAL; BEGIN( GroupDocArg1 ); + return stop; } -static void handleAddToGroup(const QCString &) +static bool handleAddToGroup(const QCString &) { - makeStructuralIndicator(Entry::GROUPDOC_SEC); + bool stop=makeStructuralIndicator(Entry::GROUPDOC_SEC); current->groupDocType = Entry::GROUPDOC_ADD; BEGIN( GroupDocArg1 ); + return stop; } -static void handleWeakGroup(const QCString &) +static bool handleWeakGroup(const QCString &) { - makeStructuralIndicator(Entry::GROUPDOC_SEC); + bool stop=makeStructuralIndicator(Entry::GROUPDOC_SEC); current->groupDocType = Entry::GROUPDOC_WEAK; BEGIN( GroupDocArg1 ); + return stop; } -static void handleNamespace(const QCString &) +static bool handleNamespace(const QCString &) { - makeStructuralIndicator(Entry::NAMESPACEDOC_SEC); + bool stop=makeStructuralIndicator(Entry::NAMESPACEDOC_SEC); BEGIN( NameSpaceDocArg1 ); + return stop; } -static void handlePackage(const QCString &) +static bool handlePackage(const QCString &) { - makeStructuralIndicator(Entry::PACKAGEDOC_SEC); + bool stop=makeStructuralIndicator(Entry::PACKAGEDOC_SEC); BEGIN( PackageDocArg1 ); + return stop; } -static void handleClass(const QCString &) +static bool handleClass(const QCString &) { - makeStructuralIndicator(Entry::CLASSDOC_SEC); + bool stop=makeStructuralIndicator(Entry::CLASSDOC_SEC); BEGIN( ClassDocArg1 ); + return stop; } -static void handleProtocol(const QCString &) +static bool handleProtocol(const QCString &) { // Obj-C protocol - makeStructuralIndicator(Entry::PROTOCOLDOC_SEC); + bool stop=makeStructuralIndicator(Entry::PROTOCOLDOC_SEC); BEGIN( ClassDocArg1 ); + return stop; } -static void handleCategory(const QCString &) +static bool handleCategory(const QCString &) { // Obj-C category - makeStructuralIndicator(Entry::CATEGORYDOC_SEC); + bool stop=makeStructuralIndicator(Entry::CATEGORYDOC_SEC); BEGIN( CategoryDocArg1 ); + return stop; } -static void handleUnion(const QCString &) +static bool handleUnion(const QCString &) { - makeStructuralIndicator(Entry::UNIONDOC_SEC); + bool stop=makeStructuralIndicator(Entry::UNIONDOC_SEC); BEGIN( ClassDocArg1 ); + return stop; } -static void handleStruct(const QCString &) +static bool handleStruct(const QCString &) { - makeStructuralIndicator(Entry::STRUCTDOC_SEC); + bool stop=makeStructuralIndicator(Entry::STRUCTDOC_SEC); BEGIN( ClassDocArg1 ); + return stop; } -static void handleInterface(const QCString &) +static bool handleInterface(const QCString &) { - makeStructuralIndicator(Entry::INTERFACEDOC_SEC); + bool stop=makeStructuralIndicator(Entry::INTERFACEDOC_SEC); BEGIN( ClassDocArg1 ); + return stop; } -static void handleIdlException(const QCString &) +static bool handleIdlException(const QCString &) { - makeStructuralIndicator(Entry::EXCEPTIONDOC_SEC); + bool stop=makeStructuralIndicator(Entry::EXCEPTIONDOC_SEC); BEGIN( ClassDocArg1 ); + return stop; } -static void handlePage(const QCString &) +static bool handlePage(const QCString &) { - makeStructuralIndicator(Entry::PAGEDOC_SEC); + bool stop=makeStructuralIndicator(Entry::PAGEDOC_SEC); BEGIN( PageDocArg1 ); + return stop; } -static void handleMainpage(const QCString &) +static bool handleMainpage(const QCString &) { - makeStructuralIndicator(Entry::MAINPAGEDOC_SEC); + bool stop=makeStructuralIndicator(Entry::MAINPAGEDOC_SEC); current->name = "mainpage"; BEGIN( PageDocArg2 ); + return stop; } -static void handleFile(const QCString &) +static bool handleFile(const QCString &) { - makeStructuralIndicator(Entry::FILEDOC_SEC); + bool stop=makeStructuralIndicator(Entry::FILEDOC_SEC); current->name = yyFileName; BEGIN( FileDocArg1 ); + return stop; } -static void handleDir(const QCString &) +static bool handleDir(const QCString &) { - makeStructuralIndicator(Entry::DIRDOC_SEC); + bool stop=makeStructuralIndicator(Entry::DIRDOC_SEC); current->name = yyFileName; BEGIN( FileDocArg1 ); + return stop; } -static void handleExample(const QCString &) +static bool handleExample(const QCString &) { - makeStructuralIndicator(Entry::EXAMPLE_SEC); + bool stop=makeStructuralIndicator(Entry::EXAMPLE_SEC); current->name = yyFileName; BEGIN( FileDocArg1 ); + return stop; } -static void handleDetails(const QCString &) +static bool handleDetails(const QCString &) { setOutput(OutputDoc); + return FALSE; } -static void handleName(const QCString &) +static bool handleName(const QCString &) { - makeStructuralIndicator(Entry::MEMBERGRP_SEC); - nameHeader.resize(0); + bool stop=makeStructuralIndicator(Entry::MEMBERGRP_SEC); + g_memberGroupHeader.resize(0); BEGIN( NameParam ); + return stop; } -static void handleTodo(const QCString &) +static bool handleTodo(const QCString &) { newXRefKind = XRef_Todo; setOutput(OutputXRef); xrefKind = XRef_Todo; + return FALSE; } -static void handleTest(const QCString &) +static bool handleTest(const QCString &) { newXRefKind = XRef_Test; setOutput(OutputXRef); xrefKind = XRef_Test; + return FALSE; } -static void handleBug(const QCString &) +static bool handleBug(const QCString &) { newXRefKind = XRef_Bug; setOutput(OutputXRef); xrefKind = XRef_Bug; + return FALSE; } -static void handleDeprecated(const QCString &) +static bool handleDeprecated(const QCString &) { newXRefKind = XRef_Deprecated; setOutput(OutputXRef); xrefKind = XRef_Deprecated; + return FALSE; } -static void handleXRefItem(const QCString &) +static bool handleXRefItem(const QCString &) { BEGIN(XRefItemParam1); + return FALSE; } -static void handleRelated(const QCString &) +static bool handleRelated(const QCString &) { BEGIN(RelatesParam1); + return FALSE; } -static void handleRelatedAlso(const QCString &) +static bool handleRelatedAlso(const QCString &) { current->relatesDup = TRUE; BEGIN(RelatesParam1); + return FALSE; } -static void handleRefItem(const QCString &) +static bool handleRefItem(const QCString &) { addOutput("@refitem "); BEGIN(LineParam); + return FALSE; } -static void handleSection(const QCString &s) +static bool handleSection(const QCString &s) { setOutput(OutputDoc); addOutput("@"+s+" "); BEGIN(SectionLabel); + return FALSE; } -static void handleSubpage(const QCString &s) +static bool handleSubpage(const QCString &s) { if (current->section!=Entry::EMPTY_SEC && current->section!=Entry::PAGEDOC_SEC && @@ -1902,43 +1964,49 @@ static void handleSubpage(const QCString &s) } addOutput("@"+s+" "); BEGIN(SubpageLabel); + return FALSE; } -static void handleAnchor(const QCString &s) +static bool handleAnchor(const QCString &s) { addOutput("@"+s+" "); BEGIN(AnchorLabel); + return FALSE; } -static void handleFormatBlock(const QCString &s) +static bool handleFormatBlock(const QCString &s) { addOutput("@"+s+" "); //printf("handleFormatBlock(%s)\n",s.data()); blockName=s; BEGIN(FormatBlock); + return FALSE; } -static void handleAddIndex(const QCString &) +static bool handleAddIndex(const QCString &) { addOutput("@addindex "); BEGIN(LineParam); + return FALSE; } -static void handleIf(const QCString &) +static bool handleIf(const QCString &) { enabledSectionFound=FALSE; guardType = Guard_If; BEGIN(GuardParam); + return FALSE; } -static void handleIfNot(const QCString &) +static bool handleIfNot(const QCString &) { enabledSectionFound=FALSE; guardType = Guard_IfNot; BEGIN(GuardParam); + return FALSE; } -static void handleElseIf(const QCString &) +static bool handleElseIf(const QCString &) { if (guards.isEmpty()) { @@ -1950,9 +2018,10 @@ static void handleElseIf(const QCString &) guardType = enabledSectionFound ? Guard_Skip : Guard_If; BEGIN(GuardParam); } + return FALSE; } -static void handleElse(const QCString &) +static bool handleElse(const QCString &) { if (guards.isEmpty()) { @@ -1963,9 +2032,10 @@ static void handleElse(const QCString &) { BEGIN( SkipGuardedSection ); } + return FALSE; } -static void handleEndIf(const QCString &) +static bool handleEndIf(const QCString &) { if (guards.isEmpty()) { @@ -1977,35 +2047,41 @@ static void handleEndIf(const QCString &) delete guards.pop(); } enabledSectionFound=FALSE; + return FALSE; } -static void handleIngroup(const QCString &) +static bool handleIngroup(const QCString &) { inGroupParamFound=FALSE; BEGIN( InGroupParam ); + return FALSE; } -static void handleNoSubGrouping(const QCString &) +static bool handleNoSubGrouping(const QCString &) { current->subGrouping = FALSE; + return FALSE; } -static void handleShowInitializer(const QCString &) +static bool handleShowInitializer(const QCString &) { current->initLines = 100000; // ON + return FALSE; } -static void handleHideInitializer(const QCString &) +static bool handleHideInitializer(const QCString &) { current->initLines = 0; // OFF + return FALSE; } -static void handleCallgraph(const QCString &) +static bool handleCallgraph(const QCString &) { current->callGraph = TRUE; // ON + return FALSE; } -static void handleInternal(const QCString &) +static bool handleInternal(const QCString &) { if (!Config_getBool("INTERNAL_DOCS")) { @@ -2015,56 +2091,67 @@ static void handleInternal(const QCString &) { addOutput("\\internal "); } + return FALSE; } -static void handleLineBr(const QCString &) +static bool handleLineBr(const QCString &) { addOutput('\n'); + return FALSE; } -static void handleStatic(const QCString &) +static bool handleStatic(const QCString &) { current->stat = TRUE; + return FALSE; } -static void handlePure(const QCString &) +static bool handlePure(const QCString &) { current->virt = Pure; + return FALSE; } -static void handlePrivate(const QCString &) +static bool handlePrivate(const QCString &) { current->protection = Private; + return FALSE; } -static void handlePrivateSection(const QCString &) +static bool handlePrivateSection(const QCString &) { current->protection = protection = Private; + return FALSE; } -static void handleProtected(const QCString &) +static bool handleProtected(const QCString &) { current->protection = Protected; + return FALSE; } -static void handleProtectedSection(const QCString &) +static bool handleProtectedSection(const QCString &) { current->protection = protection = Protected ; + return FALSE; } -static void handlePublic(const QCString &) +static bool handlePublic(const QCString &) { current->protection = Public; + return FALSE; } -static void handlePublicSection(const QCString &) +static bool handlePublicSection(const QCString &) { current->protection = protection = Public; + return FALSE; } -static void handleInherit(const QCString &) +static bool handleInherit(const QCString &) { BEGIN(InheritParam); + return FALSE; } //---------------------------------------------------------------------------- @@ -2080,13 +2167,15 @@ static void checkFormula() //---------------------------------------------------------------------------- bool parseCommentBlock(/* in */ ParserInterface *parser, - /* in,out */ Entry *curEntry, + /* in */ Entry *curEntry, /* in */ const QCString &comment, /* in */ const QCString &fileName, /* in */ int lineNr, /* in */ bool isBrief, /* in */ bool isJavaDocStyle, - /* in,out */ Protection &prot + /* in,out */ Protection &prot, + /* in,out */ int &position, + /* out */ bool &newEntryNeeded ) { //fprintf(stderr,"parseCommentBlock() isBrief=%d isJavaDocStyle=%d lineNr=%d\n", @@ -2099,7 +2188,7 @@ bool parseCommentBlock(/* in */ ParserInterface *parser, current = curEntry; inputString = comment; if (inputString==0) return FALSE; // avoid empty strings - inputPosition = 0; + inputPosition = position; yyLineNr = lineNr; yyFileName = fileName; protection = prot; @@ -2107,6 +2196,7 @@ bool parseCommentBlock(/* in */ ParserInterface *parser, xrefKind = XRef_None; xrefAppendFlag = FALSE; insidePre = FALSE; + parseMore = FALSE; outputXRef.resize(0); setOutput( isBrief || isJavaDocStyle ? OutputBrief : OutputDoc ); briefEndsAtDot = isJavaDocStyle; @@ -2136,8 +2226,143 @@ bool parseCommentBlock(/* in */ ParserInterface *parser, checkFormula(); prot = protection; + + groupAddDocs(curEntry,fileName); + + newEntryNeeded = needNewEntry; + + if (parseMore) position=inputPosition; else position=0; + + return parseMore; +} + +//--------------------------------------------------------------------------- + +void groupEnterFile(const char *,int) +{ + g_autoGroupStack.setAutoDelete(TRUE); + g_autoGroupStack.clear(); + g_memberGroupId = DOX_NOGROUP; + g_memberGroupDocs.resize(0); + g_memberGroupRelates.resize(0); +} + +void groupLeaveFile(const char *fileName,int line) +{ + if (g_memberGroupId!=DOX_NOGROUP) + { + warn(fileName,line,"Warning: end of file while inside a member group\n"); + } + if (!g_autoGroupStack.isEmpty()) + { + warn(fileName,line,"Warning: end of file while inside a group\n"); + } +} + +void groupEnterCompound(const char *fileName,int line,const char *name) +{ + if (g_memberGroupId!=DOX_NOGROUP) + { + warn(fileName,line,"Warning: try to put compound %s inside a member group\n",name); + } + g_memberGroupId=DOX_NOGROUP; + g_memberGroupRelates.resize(0); + g_memberGroupDocs.resize(0); +} - return needNewEntry; +void groupLeaveCompound(const char *fileName,int line,const char *name) +{ + if (g_memberGroupId!=DOX_NOGROUP) + { + warn(fileName,line,"Warning: end of compound %s while inside a member group\n",name); + } + g_memberGroupId=DOX_NOGROUP; + g_memberGroupRelates.resize(0); + g_memberGroupDocs.resize(0); +} + + +void closeGroup(Entry *e,const char *fileName,int) +{ + //printf("%s:%d: closeGroup()\n",fileName,line); + if (g_memberGroupId!=DOX_NOGROUP) // end of member group + { + MemberGroupInfo *info=Doxygen::memGrpInfoDict.find(g_memberGroupId); + if (info) // know group + { + info->doc = g_memberGroupDocs; + info->docFile = fileName; + } + g_memberGroupId=DOX_NOGROUP; + g_memberGroupRelates.resize(0); + g_memberGroupDocs.resize(0); + e->mGrpId=DOX_NOGROUP; + //printf("new group id=%d\n",g_memberGroupId); + } + else if (!g_autoGroupStack.isEmpty()) // end of auto group + { + delete g_autoGroupStack.pop(); + } +} + +void openGroup(Entry *e,const char *fileName,int line) +{ + //printf("%s:%d: openGroup(sec=%x)\n",fileName,line,e->section); + if (e->section==Entry::GROUPDOC_SEC) // auto group + { + g_autoGroupStack.push(new Grouping(e->name,e->groupingPri())); + } + else // start of a member group + { + if (g_memberGroupId!=DOX_NOGROUP) + { + warn(fileName,line,"Warning: member groups cannot be nested. Ending current group!\n"); + closeGroup(e,fileName,line); + } + static int curGroupId=0; + g_memberGroupId = curGroupId++; + //printf("new group id=%d header=%s\n",g_memberGroupId,g_memberGroupHeader.data()); + + MemberGroupInfo *info = new MemberGroupInfo; + info->header = g_memberGroupHeader.stripWhiteSpace(); + Doxygen::memGrpInfoDict.insert(g_memberGroupId,info); + + g_memberGroupRelates = e->relates; + e->mGrpId = g_memberGroupId; + } +} + +void initGroupInfo(Entry *e) +{ + e->mGrpId = g_memberGroupId; + e->relates = g_memberGroupRelates; + if (!g_autoGroupStack.isEmpty()) + { + //printf("Appending group %s\n",autoGroupStack.top()->groupname.data()); + e->groups->append(new Grouping(*g_autoGroupStack.top())); + } +} + +static void groupAddDocs(Entry *e,const char *fileName) +{ + if (e->section==Entry::MEMBERGRP_SEC) + { + g_memberGroupDocs=e->brief.stripWhiteSpace(); + e->doc = stripLeadingAndTrailingEmptyLines(e->doc); + if (!g_memberGroupDocs.isEmpty() && !e->doc.isEmpty()) + { + g_memberGroupDocs+="\n\n"; + } + g_memberGroupDocs+=e->doc; + MemberGroupInfo *info=Doxygen::memGrpInfoDict.find(g_memberGroupId); + if (info) + { + info->doc = g_memberGroupDocs; + info->docFile = fileName; + } + e->doc.resize(0); + e->brief.resize(0); + } } diff --git a/src/config.l b/src/config.l index 1e49a28..a9ca7c0 100644 --- a/src/config.l +++ b/src/config.l @@ -1838,7 +1838,9 @@ void Config::create() "EXCLUDE_PATTERNS", "If the value of the INPUT tag contains directories, you can use the \n" "EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude \n" - "certain files from those directories. \n" + "certain files from those directories. Note that the wildcards are matched \n" + "against the file with absolute path, so to exclude all test directories \n" + "for example use the pattern */test/* \n" ); cl = addList( "EXAMPLE_PATH", diff --git a/src/doctokenizer.l b/src/doctokenizer.l index b2be204..6cc93d1 100644 --- a/src/doctokenizer.l +++ b/src/doctokenizer.l @@ -302,7 +302,8 @@ FILEECHAR [a-z_A-Z0-9\-\+] HFILEMASK ("."{FILESCHAR}*{FILEECHAR}+)* FILEMASK ({FILESCHAR}*{FILEECHAR}+("."{FILESCHAR}*{FILEECHAR}+)*)|{HFILEMASK} LINKMASK [^ \t\n\r\\@<&${}]+("("[^\n)]*")")?({BLANK}*("const"|"volatile"){BLANK}+)? -SPCMD1 {CMD}[a-z_A-Z0-9]+ +VERBATIM "verbatim"{BLANK}* +SPCMD1 {CMD}([a-z_A-Z0-9]+|{VERBATIM}) SPCMD2 {CMD}[\\@<>&$#%~] SPCMD3 {CMD}form#[0-9]+ INOUT "in"|"out"|("in"{BLANK}*","{BLANK}*"out")|("out"{BLANK}*","{BLANK}*"in") @@ -324,6 +325,7 @@ OPMASK ({BLANK}*{OPNORM}{FUNCARG}?)|({OPCAST}{FUNCARG}) LNKWORD1 ("::"|"#")?{SCOPEMASK} CVSPEC {BLANK}*("const"|"volatile") LNKWORD2 {SCOPEPRE}*"operator"{OPMASK} +LNKWORD3 [0-9a-z_A-Z]+("."[0-9a-z_A-Z]+)+ CHARWORD [^ \t\n\r\\@<>()\[\]:;\?{}&%$#,.] CHARWORDQ [^ \t\n\r\\@<>()\[\]:;\?{}&%$#,."] WORD1 "%"?{CHARWORD}+|"{"|"}"|("\""[^"\n]*"\"") @@ -416,6 +418,7 @@ REFWORD ("#"|"::")?({ID}("."|"#"|"::"|"-"))*({ID}(":")?){FUNCARG}? <St_Para>{SPCMD1} | <St_Para>{SPCMD2} { /* special command */ g_token->name = yytext+1; + g_token->name = g_token->name.stripWhiteSpace(); g_token->paramDir=TokenInfo::Unspecified; return TK_COMMAND; } @@ -488,7 +491,8 @@ REFWORD ("#"|"::")?({ID}("."|"#"|"::"|"-"))*({ID}(":")?){FUNCARG}? <St_Para>{LNKWORD1}/"<br>" | // prevent <br> html tag to be parsed as template arguments <St_Para>{LNKWORD1} | <St_Para>{LNKWORD1}{FUNCARG} | -<St_Para>{LNKWORD2} { +<St_Para>{LNKWORD2} | +<St_Para>{LNKWORD3} { g_token->name = yytext; return TK_LNKWORD; } diff --git a/src/doxygen.cpp b/src/doxygen.cpp index e45f91c..8a78ea9 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -1582,19 +1582,24 @@ static MemberDef *addVariableToFile( } } QCString def; + // determine the definition of the global variable if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@' && !Config_getBool("HIDE_SCOPE_NAMES") ) // variable is inside a namespace, so put the scope before the name { + static bool optimizeForJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA"); + QCString sep="::"; + if (optimizeForJava) sep="."; + if (!root->type.isEmpty()) { - def=root->type+" "+nd->name()+"::"+name+root->args; + def=root->type+" "+nd->name()+sep+name+root->args; } else { - def=nd->name()+"::"+name+root->args; + def=nd->name()+sep+name+root->args; } } else diff --git a/src/memberdef.cpp b/src/memberdef.cpp index a18e1fc..3e9becf 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -2070,10 +2070,16 @@ MemberDef *MemberDef::createTemplateInstanceMember( actualArgList->pureSpecifier = defArgList->pureSpecifier; } + QCString methodName=name(); + if (methodName.left(9)=="operator ") // conversion operator + { + methodName=substituteTemplateArgumentsInString(methodName,formalArgs,actualArgs); + } + MemberDef *imd = new MemberDef( getDefFileName(),getDefLine(), substituteTemplateArgumentsInString(type,formalArgs,actualArgs), - name(), + methodName, substituteTemplateArgumentsInString(args,formalArgs,actualArgs), exception, prot, virt, stat, related, mtype, 0, 0 diff --git a/src/outputgen.h b/src/outputgen.h index 1146f4d..e92d633 100644 --- a/src/outputgen.h +++ b/src/outputgen.h @@ -42,6 +42,7 @@ class GroupDef; class CodeOutputInterface { public: + virtual ~CodeOutputInterface() {} /*! Writes an ASCII string to the output. This function should keep * spaces visible, should break lines at a newline and should convert * tabs to the right number of spaces. @@ -81,6 +82,7 @@ class CodeOutputInterface class BaseOutputDocInterface : public CodeOutputInterface { public: + virtual ~BaseOutputDocInterface() {} enum ParamListTypes { Param, RetVal, Exception }; enum SectionTypes { /*See, Return, Author, Version, Since, Date, Bug, Note, diff --git a/src/parserintf.h b/src/parserintf.h index ac81a72..ce1f649 100644 --- a/src/parserintf.h +++ b/src/parserintf.h @@ -95,17 +95,6 @@ class ParserInterface */ virtual void parsePrototype(const char *text) = 0; - /** Callback function called by the comment block scanner upon encountering - * a group block start command (@@{). If the group has a header - * specified via the @@name command, this will be passed via - * the \a header parameter, if not the \a header parameter will be 0. - */ - virtual void handleGroupStartCommand(const char *header) = 0; - - /** Callback function called by the comment block scanner upon encountering - * a group block end command (@@}). - */ - virtual void handleGroupEndCommand() = 0; }; //----------------------------------------------------------------------------- diff --git a/src/pycode.l b/src/pycode.l index dca57ca..175556a 100644 --- a/src/pycode.l +++ b/src/pycode.l @@ -71,8 +71,8 @@ static QCString g_name; static bool g_doubleStringIsDoc; static bool g_doubleQuote; -static int g_lastState; static bool g_noSuiteFound; +static int g_stringContext; static QValueStack<uint> g_indents; //!< Tracks indentation levels for scoping in python @@ -349,6 +349,7 @@ static void startCodeLine() g_insideBody = FALSE; g_searchingForBody = TRUE; g_realScope = d->name().copy(); + g_classScope = d->name().copy(); //printf("Real scope: `%s'\n",g_realScope.data()); g_bodyCurlyCount = 0; QCString lineAnchor; @@ -709,6 +710,56 @@ static void generateFunctionLink(CodeOutputInterface &ol,char *funcName) return; } +static void findMemberLink(CodeOutputInterface &ol,const char *symName) +{ + //printf("Member reference: %s scope=%s member=%s\n", + // yytext, + // g_currentDefinition?g_currentDefinition->name().data():"<none>", + // g_currentMemberDef?g_currentMemberDef->name().data():"<none>" + // ); + if (g_currentDefinition) + { + DefinitionList *dl = Doxygen::symbolMap->find(symName); + if (dl) + { + DefinitionListIterator dli(*dl); + Definition *sym; + for (dli.toFirst();(sym=dli.current());++dli) + { + //printf("sym %s outerScope=%s equal=%d\n", + // sym->name().data(),sym->getOuterScope()->name().data(), + // sym->getOuterScope()==g_currentDefinition); + + if (sym->getOuterScope() && + sym->getOuterScope()->definitionType()==Definition::TypeClass && + g_currentDefinition->definitionType()==Definition::TypeClass) + { + ClassDef *cd = (ClassDef*)sym->getOuterScope(); + ClassDef *thisCd = (ClassDef *)g_currentDefinition; + QCString anchor; + if (sym->definitionType()==Definition::TypeMember) + { + anchor=((MemberDef *)sym)->anchor(); + } + + // TODO: find the nearest base class in case cd is a base class of + // thisCd + if (cd==thisCd) + { + writeMultiLineCodeLink(ol,sym->getReference(), + sym->getOutputFileBase(), + anchor, + symName); + return; + } + } + } + } + } + //printf("sym %s not found\n",&yytext[5]); + codify(yytext); +} + static void startFontClass(const char *s) { endFontClass(); @@ -855,8 +906,6 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBUT %x Body -%x BlockWord - %x FunctionDec %x FunctionParams @@ -871,130 +920,12 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBUT %x LongString +%x SingleQuoteString +%x DoubleQuoteString +%x TripleString %% -<Body,Suite,SuiteCaptureIndent>{ - {B}{POUNDCOMMENT} { - // This eats EVERYTHING - // except the newline - startFontClass("comment"); - codifyLines(yytext); - endFontClass(); - } - - {B}{STRINGPREFIX}?{TRIDOUBLEQUOTE}({LONGSTRINGBLOCK}?) { - // Some-what position sensitive; - // must come before NONEMPTY general - // rules. - - // Eventually, we should write some intelligent - // code here to figure out if this docstring - // should be deleted. - g_doubleStringIsDoc = TRUE; - - if ( g_doubleStringIsDoc ) - { - g_yyLineNr+=QCString(yytext).contains('\n'); - } - else - { - startFontClass("stringliteral"); - codifyLines(yytext); - g_yyLineNr++; - } - - g_lastState = YY_START; - g_doubleQuote = TRUE; - - BEGIN( LongString ); - } - - {B}{STRINGPREFIX}?{TRISINGLEQUOTE}({LONGSTRINGBLOCK}?) { - //startFontClass("stringliteral"); - //codifyLines(yytext); - - // Eventually, we should write some intelligent - // code here to figure out if this docstring - // should be deleted. - g_doubleStringIsDoc = TRUE; - - if ( g_doubleStringIsDoc ) - { - g_yyLineNr+=QCString(yytext).contains('\n'); - } - else - { - startFontClass("stringliteral"); - codifyLines(yytext); - g_yyLineNr++; - } - - g_lastState = YY_START; - g_doubleQuote = FALSE; - BEGIN( LongString ); - } - -} - -<Body,Suite,BlockWord>{ - {STRINGPREFIX}?({SINGLEQUOTES}|{QUOTES}) { - startFontClass("stringliteral"); - codifyLines(yytext); - endFontClass(); - } - - "#".* { - startFontClass("stringliteral"); - codifyLines(yytext); - endFontClass(); - } - -} - -<LongString>{ - - {LONGSTRINGBLOCK} { - if ( g_doubleStringIsDoc ) - { - g_yyLineNr+=QCString(yytext).contains('\n'); - } - else - { - codifyLines(yytext); - } - } - - {TRIDOUBLEQUOTE} { - if ( ! g_doubleStringIsDoc ) - { - codify(yytext); - endFontClass(); - } - - if (g_doubleQuote) - { - g_doubleStringIsDoc = FALSE; - BEGIN( g_lastState ); - } - } - - {TRISINGLEQUOTE} { - if ( ! g_doubleStringIsDoc ) - { - codify(yytext); - endFontClass(); - } - - if (!g_doubleQuote) - { - g_doubleStringIsDoc = FALSE; - BEGIN( g_lastState ); - } - } -} - - <Body,Suite>{ "def"{BB} { startFontClass("keyword"); @@ -1009,6 +940,15 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBUT endFontClass(); BEGIN( ClassDec ); } + "None" { + startFontClass("keywordtype"); + codify(yytext); + endFontClass(); + } + "self."{IDENTIFIER} { + codify("self."); + findMemberLink(*g_code,&yytext[5]); + } } <ClassDec>{IDENTIFIER} { @@ -1124,15 +1064,7 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBUT } } -<Body,Suite>("if"|"while"|"for"|"else"|"elif") { - startFontClass("keywordflow"); - codify(yytext); - endFontClass(); - // printf("Entering Blockword on '%s' [%d]\n", yytext, g_yyLineNr); - - } - -<Body,Suite,BlockWord>{ +<Body,Suite>{ {KEYWORD} { // Position-sensitive rules! @@ -1150,38 +1082,19 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBUT codify(yytext); endFontClass(); } -} - -<BlockWord>{ - - ":" { - codify(yytext); - // printf("Requires SuiteState for BlockWord [line %d]\n", g_yyLineNr); - // Assume this will - // be a one-line suite; - // found counter-example - // in SuiteStart. - g_noSuiteFound = TRUE; - BEGIN( SuiteStart ); - } - - ({BB}+|{NONEMPTY}+|{EXPCHAR}) { // Position-sensitive! Must come AFTER - // key-word catching rules, so that syntax - // highlighting takes priority over this. + {IDENTIFIER} { + codify(yytext); + } +} - // Match SPACE, IDENTIFIERS, or EXPchars. - codify(yytext); - } -} <SuiteStart>{ {BB} { codify(yytext); } - {KEYWORD} { startFontClass("keyword"); codifyLines(yytext); @@ -1199,13 +1112,9 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBUT // No indentation necesary g_noSuiteFound = FALSE; } - - ({NONEMPTY}+|{EXPCHAR}+) { - codifyLines(yytext); - - // No indentation necesary - g_noSuiteFound = FALSE; - } + {IDENTIFIER} { + codify(yytext); + } {POUNDCOMMENT} { @@ -1274,33 +1183,134 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBUT <Suite>{NEWLINE} { - codifyLines(yytext); - BEGIN( SuiteMaintain ); + codifyLines(yytext); + BEGIN( SuiteMaintain ); } +<Body>{IDENTIFIER} { + codify(yytext); + } +<Body>{NEWLINE} { + codifyLines(yytext); + } -<Body,Suite>({NONEMPTY}+|{EXPCHAR}+|{BB}) { +<SingleQuoteString>{ // Single quoted string like 'That\'s a """nice""" string!' + \\{B}\n { // line continuation + codifyLines(yytext); + } + \\. { // espaced char + codify(yytext); + } + {STRINGPREFIX}?{TRIDOUBLEQUOTE} { // tripple double quotes + codify(yytext); + } + "'" { // end of the string + codify(yytext); + endFontClass(); + BEGIN(g_stringContext); + } + [^"'\n\\]+ { // normal chars codify(yytext); } + . { // normal char + codify(yytext); + } +} -<Body>{NEWLINE} { +<DoubleQuoteString>{ // Double quoted string like "That's \"a '''nice'''\" string!" + \\{B}\n { // line continuation codifyLines(yytext); } + \\. { // espaced char + codify(yytext); + } + {STRINGPREFIX}?{TRISINGLEQUOTE} { // tripple single quotes + codify(yytext); + } + "\"" { // end of the string + codify(yytext); + endFontClass(); + BEGIN(g_stringContext); + } + [^"'\n\\]+ { // normal chars + codify(yytext); + } + . { // normal char + codify(yytext); + } +} + +<TripleString>{ + {TRIDOUBLEQUOTE} | + {TRISINGLEQUOTE} { + codify(yytext); + if (g_doubleQuote==(yytext[0]=='"')) + { + endFontClass(); + BEGIN(g_stringContext); + } + } + {LONGSTRINGBLOCK} { + codifyLines(yytext); + } + \n { + codifyLines(yytext); + } + . { + codify(yytext); + } +} + /* <*>({NONEMPTY}|{EXPCHAR}|{BB}) { // This should go one character at a time. codify(yytext); // printf("[pycode] '%s' [ state %d ] [line %d] no match\n", // yytext, YY_START, g_yyLineNr); - endFontClass(); + //endFontClass(); BEGIN(Body); } + */ +<*>{STRINGPREFIX}?{TRISINGLEQUOTE} | +<*>{STRINGPREFIX}?{TRIDOUBLEQUOTE} { + startFontClass("stringliteral"); + g_stringContext=YY_START; + g_doubleQuote=yytext[yyleng-1]=='"'; + codify(yytext); + BEGIN(TripleString); + } +<*>{STRINGPREFIX}?"'" { // single quoted string + startFontClass("stringliteral"); + g_stringContext=YY_START; + codify(yytext); + BEGIN(SingleQuoteString); + } +<*>{STRINGPREFIX}?"\"" { // double quoted string + startFontClass("stringliteral"); + g_stringContext=YY_START; + codify(yytext); + BEGIN(DoubleQuoteString); + } +<*>{POUNDCOMMENT} { + if (YY_START==SingleQuoteString || + YY_START==DoubleQuoteString || + YY_START==TripleString + ) + { + REJECT; + } + // This eats EVERYTHING + // except the newline + startFontClass("comment"); + codifyLines(yytext); + endFontClass(); + } <*>{NEWLINE} { codifyLines(yytext); //printf("[pycode] %d NEWLINE [line %d] no match\n", // YY_START, g_yyLineNr); - endFontClass(); + //endFontClass(); BEGIN(Body); } @@ -1309,7 +1319,7 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBUT // printf("[pycode] '%s' [ state %d ] [line %d] no match\n", // yytext, YY_START, g_yyLineNr); - endFontClass(); + //endFontClass(); BEGIN(Body); } diff --git a/src/pyscanner.h b/src/pyscanner.h index 6b40ddf..7ec7e40 100644 --- a/src/pyscanner.h +++ b/src/pyscanner.h @@ -49,8 +49,6 @@ class PythonLanguageScanner : public ParserInterface ); void resetCodeParserState(); void parsePrototype(const char *text); - void handleGroupStartCommand(const char *header); - void handleGroupEndCommand(); }; #endif diff --git a/src/pyscanner.l b/src/pyscanner.l index f2ebb4c..650e51e 100644 --- a/src/pyscanner.l +++ b/src/pyscanner.l @@ -36,6 +36,7 @@ #include <qregexp.h> #include <unistd.h> #include <qfile.h> +#include <qfileinfo.h> #include "pyscanner.h" #include "entry.h" @@ -54,71 +55,23 @@ * * statics */ + + static ParserInterface *g_thisParser; static const char * inputString; static int inputPosition; static QFile inputFile; static Protection protection; -static Protection baseProt; - -int tabsize = 0; -static QStack<int> spaceStack; -static int sharpCount = 0 ; -static int roundCount = 0 ; -static int curlyCount = 0 ; -static int padCount = 0 ; -static QCString slString; static Entry* current_root = 0 ; -static Entry* global_root = 0 ; static Entry* current = 0 ; static Entry* previous = 0 ; static int yyLineNr = 1 ; -static int anonCount = 0 ; static QCString yyFileName; static MethodTypes mtype; static bool gstat; static Specifier virt; -static Specifier baseVirt; -static QCString msType,msName,msArgs; -static int memberGroupId = DOX_NOGROUP; -static QCString memberGroupHeader; -static QCString memberGroupDocs; -static bool isTypedef; -//static char afterDocTerminator; -static QCString sectionLabel; -static QCString sectionTitle; -//static SectionInfo::SectionType -// sectionType; -static QCString funcPtrType; -static QCString templateStr; -static QCString aliasName; -static QCString baseName; -static QCString formulaText; -static QCString formulaEnd; - -static QCString fullArgString; - -//static QCString *currentTemplateSpec; -static QStack<Grouping> autoGroupStack; -static Grouping lastDefGroup( "", Grouping::GROUPING_LOWEST ); - -static bool insideFormula; -static bool insideTryBlock=FALSE; -static bool insideCode; - -static int depthIf; -static QCString memberGroupRelates; -static QCString memberGroupInside; -static QCString xrefItemKey; -static QCString xrefItemTitle; -static QCString xrefListTitle; - -static QCString g_skipBlockName; -static QCString oldStyleArgType; -static QCString docBackup; -static QCString briefBackup; static int docBlockContext; static QCString docBlock; @@ -129,40 +82,32 @@ static bool docBrief; static bool g_doubleQuote; static bool g_specialBlock; +static bool g_expectModuleDocs; +static int g_stringContext; +static QCString * g_copyString; +static int g_indent = 0; -int g_indent = 0; -int class_indent = 0; -int classKeywordIndent = 0; +static QDict<QCString> g_packageNameCache(257); +static QCString g_packageScope; + +static char g_atomStart; +static char g_atomEnd; +static int g_atomCount; + +static bool g_insideConstructor; +static Entry * g_constructorEntry = 0; //----------------------------------------------------------------------------- static void initParser() { - sectionLabel.resize(0); - sectionTitle.resize(0); - baseName.resize(0); - formulaText.resize(0); protection = Public; - baseProt = Public; - sharpCount = 0; - roundCount = 0; - curlyCount = 0; - memberGroupId = DOX_NOGROUP; - memberGroupRelates.resize(0); - memberGroupInside.resize(0); mtype = Method; gstat = FALSE; virt = Normal; - baseVirt = Normal; - isTypedef = FALSE; - autoGroupStack.clear(); - insideTryBlock = FALSE; - autoGroupStack.setAutoDelete(TRUE); - lastDefGroup.groupname.resize(0); - insideFormula = FALSE; - insideCode=FALSE; previous = 0; + g_packageNameCache.setAutoDelete(TRUE); } static void initEntry() @@ -172,18 +117,79 @@ static void initEntry() current->mtype = mtype; current->virt = virt; current->stat = gstat; - current->mGrpId = memberGroupId; - current->relates = memberGroupRelates.copy(); - current->inside = memberGroupInside.copy(); current->objc = FALSE; //insideObjC; current->parent = current_root; - if (!autoGroupStack.isEmpty()) + initGroupInfo(current); +} + +static void newEntry() +{ + previous = current; + current_root->addSubEntry(current); + current = new Entry ; + initEntry(); +} + +static void newVariable() +{ + if (!current->name.isEmpty() && current->name.at(0)=='_') // mark as private + { + current->protection=Private; + } + if (current_root->section&Entry::SCOPE_MASK) // mark as class variable { - //printf("Appending group %s\n",autoGroupStack.top()->groupname.data()); - current->groups->append(new Grouping(*autoGroupStack.top())); + current->stat = TRUE; } + newEntry(); } +static inline int computeIndent(const char *s) +{ + int col=0; + static int tabSize=Config_getInt("TAB_SIZE"); + const char *p=s; + char c; + while ((c=*p++)) + { + if (c==' ') col++; + else if (c=='\t') col+=tabSize-(col%tabSize); + else break; + } + return col; +} + +static QCString findPackageScopeFromPath(const QCString &path) +{ + QCString *pScope = g_packageNameCache.find(path); + if (pScope) + { + return *pScope; + } + QFileInfo pf(path+"/__init__.py"); // found package initialization file + if (pf.exists()) + { + int i=path.findRev('/'); + if (i!=-1) + { + QCString scope = findPackageScopeFromPath(path.left(i)); + if (!scope.isEmpty()) + { + scope+="::"; + } + scope+=path.mid(i+1); + g_packageNameCache.insert(path,new QCString(scope)); + return scope; + } + } + return ""; +} + +static QCString findPackageScope(const char *fileName) +{ + if (fileName==0) return ""; + QFileInfo fi(fileName); + return findPackageScopeFromPath(fi.dirPath(TRUE).data()); +} //----------------------------------------------------------------------------- @@ -230,25 +236,6 @@ static QCString stripQuotes(const char *s) #endif //----------------------------------------------------------------- -static void addMemberGroupDocs() -{ - memberGroupDocs=current->brief.stripWhiteSpace(); - current->doc = current->doc.stripWhiteSpace(); - if (!memberGroupDocs.isEmpty() && !current->doc.isEmpty()) - { - memberGroupDocs+="\n\n"; - } - memberGroupDocs+=current->doc; - MemberGroupInfo *info=Doxygen::memGrpInfoDict.find(memberGroupId); - if (info) - { - info->doc = memberGroupDocs; - info->docFile = yyFileName; - } - current->doc.resize(0); - current->brief.resize(0); -} - //----------------------------------------------------------------- static void startCommentBlock(bool brief) { @@ -286,28 +273,81 @@ static void handleCommentBlock(const QCString &doc,bool brief) previous->doc=previous->doc.stripWhiteSpace()+"\n\n"; } - if (parseCommentBlock( + int position = 0; + bool needsEntry; + while (parseCommentBlock( g_thisParser, (docBlockInBody && previous) ? previous : current, doc, // text yyFileName, // file brief ? current->briefLine : current->docLine, // line of block start docBlockInBody ? FALSE : brief, - FALSE, // javadoc style - protection) + docBlockJavaStyle, // javadoc style + protection, + position, + needsEntry) ) // need to start a new entry { - // printf("adding node to nodelist..."); - if (current->section==Entry::MEMBERGRP_SEC) + if (needsEntry) { - addMemberGroupDocs(); + newEntry(); } - current_root->addSubEntry(current); - previous = current; - current = new Entry ; - initEntry(); } + if (needsEntry) + { + newEntry(); + } + +} + +static void endOfDef() +{ + if (g_insideConstructor) + { + g_constructorEntry->endBodyLine = yyLineNr; + } + else + { + current->endBodyLine = yyLineNr; + newEntry(); + } + g_insideConstructor = FALSE; + g_constructorEntry = 0; +} + +static inline void addToString(const char *s) +{ + if (g_copyString) (*g_copyString)+=s; +} +static void initTriDoubleQuoteBlock() +{ + docBlockContext = YY_START; + docBlockInBody = FALSE; + docBlockJavaStyle = TRUE; + docBlock.resize(0); + g_doubleQuote = TRUE; + startCommentBlock(FALSE); +} + +static void initTriSingleQuoteBlock() +{ + docBlockContext = YY_START; + docBlockInBody = FALSE; + docBlockJavaStyle = TRUE; + docBlock.resize(0); + g_doubleQuote = FALSE; + startCommentBlock(FALSE); +} + +static void initSpecialBlock() +{ + docBlockContext = YY_START; + docBlockInBody = FALSE; + docBlockJavaStyle = TRUE; + docBrief = TRUE; + docBlock.resize(0); + startCommentBlock(TRUE); } //----------------------------------------------------------------------------- @@ -339,6 +379,12 @@ NEWLINE \n BN [ \t\n] DIGIT [0-9] + +HEXNUMBER "0"[xX][0-9a-fA-F]+[lL]? +OCTNUMBER "0"[0-7]+[lL]? +NUMBER {DIGIT}+[lLjJ]? +INTNUMBER {HEXNUMBER}|{OCTNUMBER}|{NUMBER} +FLOATNUMBER {DIGIT}+"."{DIGIT}+([eE][+\-]?{DIGIT}+)?[jJ]? LETTER [A-Za-z] NONEMPTY [A-Za-z0-9_] EXPCHAR [#(){}\[\],:.%/\\=`*~|&<>!;+-] @@ -347,8 +393,6 @@ PARAMNONEMPTY [^ \t\n():] IDENTIFIER ({LETTER}|"_")({LETTER}|{DIGIT}|"_")* BORDER ([^A-Za-z0-9]) -POUNDCOMMENT "#".* - TRISINGLEQUOTE "'''" TRIDOUBLEQUOTE "\"\"\"" LONGSTRINGCHAR [^\\"'] @@ -364,42 +408,235 @@ STRINGLITERAL {STRINGPREFIX}?( {SHORTSTRING} | {LONGSTRING}) STRINGPREFIX ("r"|"u"|"ur"|"R"|"U"|"UR"|"Ur"|"uR") KEYWORD ("lambda"|"import"|"class"|"assert"|"as"|"from"|"global"|"def"|"True"|"False") FLOWKW ("or"|"and"|"is"|"not"|"print"|"for"|"in"|"if"|"try"|"except"|"yield"|"raise"|"break"|"continue"|"pass"|"if"|"return"|"while"|"elif"|"else"|"finally") -QUOTES ("\""[^"]*"\"") -SINGLEQUOTES ("'"[^']*"'") +POUNDCOMMENT {B}"#"[^#\n][^\n]* -STARTDOCSYMS "##" +STARTDOCSYMS ^{B}"##"/[^#] %option noyywrap -%option nounput /* Main start state */ -%x Body +%x Search /* Mid-comment states */ /* %x FuncDoubleComment */ /* %x ClassDoubleComment */ %x TryClassDocString -%x MultiDoubleComment +%x TripleComment %x SpecialComment /* Function states */ %x FunctionDec %x FunctionParams +%x FunctionBody /* Class states */ %x ClassDec %x ClassInheritance %x ClassCaptureIndent +%x ClassBody + + /* Variable states */ +%x VariableDec +%x VariableEnd +%x VariableAtom + + /* String states */ +%x SingleQuoteString +%x DoubleQuoteString +%x TripleString %% /* ------------ Function recognition rules -------------- */ +<Search>{ + + ^{B}"def"{BB} { // start of a function/method definition + g_indent=computeIndent(yytext); + g_expectModuleDocs = FALSE; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + current->section = Entry::FUNCTION_SEC; + current->protection = protection = Public; + current->objc = FALSE; + current->virt = Normal; + current->stat = FALSE; + current->mtype = mtype = Method; + current->type.resize(0); + current->name.resize(0); + current->args.resize(0); + current->argList->clear(); + BEGIN( FunctionDec ); + } + + ^{B}"class"{BB} { // start of a class definition + g_indent=computeIndent(yytext); + g_expectModuleDocs = FALSE; + current->section = Entry::CLASS_SEC; + current->argList->clear(); + current->type += "class" ; + current->fileName = yyFileName; + current->bodyLine = yyLineNr; + + BEGIN( ClassDec ) ; + } + + ^{B}{IDENTIFIER}/{B}"="[^=] { // variable + g_indent=computeIndent(yytext); + current->section = Entry::VARIABLE_SEC; + current->name = QCString(yytext).stripWhiteSpace(); + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + BEGIN(VariableDec); + } + "'" { // start of a single quoted string + g_stringContext=YY_START; + g_copyString=0; + BEGIN( SingleQuoteString ); + } + "\"" { // start of a double quoted string + g_stringContext=YY_START; + g_copyString=0; + BEGIN( DoubleQuoteString ); + } + + {POUNDCOMMENT} { // normal comment + } + {IDENTIFIER} { // some other identifier + } + + [^\n] { // any other character... + // This is the major default + // that should catch everything + // else in Body. + } + + {NEWLINE}+ { // new line + lineCount(); + } + + {TRIDOUBLEQUOTE} { // start of a comment block + initTriDoubleQuoteBlock(); + BEGIN(TripleComment); + } + + {TRISINGLEQUOTE} { // start of a comment block + initTriSingleQuoteBlock(); + BEGIN(TripleComment); + } + + {STARTDOCSYMS} { // start of a special comment + initSpecialBlock(); + BEGIN(SpecialComment); + } +} + +<FunctionBody>{ + \n{B}/{IDENTIFIER}{BB} { + //fprintf(stderr,"indent %d<=%d\n",computeIndent(&yytext[1]),g_indent); + if (computeIndent(&yytext[1])<=g_indent) + { + int i; + for (i=yyleng-1;i>=0;i--) + { + unput(yytext[i]); + } + endOfDef(); + BEGIN(Search); + } + else + { + yyLineNr++; + } + } + \n/{B}"##" { + unput('\n'); + endOfDef(); + BEGIN(Search); + } + <<EOF>> { + endOfDef(); + yyterminate(); + } + "self."{IDENTIFIER}/{B}"=" { + if (g_insideConstructor) + { + current->name=&yytext[5]; + current->section=Entry::VARIABLE_SEC; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + current->type.resize(0); + if (!current->name.isEmpty() && current->name.at(0)=='_') // mark as private + { + current->protection=Private; + } + else + { + current->protection=Public; + } + newEntry(); + } + } + ^{BB}\n { // skip empty line + yyLineNr++; + } + ^{BB} { // something at indent >0 + if (computeIndent(yytext)<=g_indent) + // jumped out of the function + { + endOfDef(); + BEGIN(Search); + } + } + "'" { // start of a single quoted string + g_stringContext=YY_START; + g_specialBlock = FALSE; + g_copyString=0; + BEGIN( SingleQuoteString ); + } + "\"" { // start of a double quoted string + g_stringContext=YY_START; + g_specialBlock = FALSE; + g_copyString=0; + BEGIN( DoubleQuoteString ); + } + [^ \t\n#'".]+ { // non-special stuff + g_specialBlock = FALSE; + } + ^{POUNDCOMMENT} { // normal comment + } + "#".* { // comment half way + } + {NEWLINE} { yyLineNr++; } + . { // any character + g_specialBlock = FALSE; + } + + {TRIDOUBLEQUOTE} { // start of a comment block + initTriDoubleQuoteBlock(); + BEGIN(TripleComment); + } + + {TRISINGLEQUOTE} { // start of a comment block + initTriSingleQuoteBlock(); + BEGIN(TripleComment); + } + + {STARTDOCSYMS} { // start of a special comment + initSpecialBlock(); + BEGIN(SpecialComment); + } + +} + <FunctionDec>{ {IDENTIFIER} { @@ -408,10 +645,19 @@ STARTDOCSYMS "##" { current->type = "def"; } - current->name = yytext; current->name = current->name.stripWhiteSpace(); - current->fileName = yyFileName; + if (!current->name.isEmpty() && current->name.at(0)=='_') + { + current->protection = Private; + } + if ((current_root->section&Entry::SCOPE_MASK) && + current->name=="__init__") // constructor + { + g_insideConstructor = TRUE; + g_constructorEntry = current; + newEntry(); + } } {B}"(" { @@ -443,130 +689,318 @@ STARTDOCSYMS "##" ")" { // end of parameter list } - ":"{BN}* { - lineCount(); - - // Push the entry. - previous = current; - current_root->addSubEntry(current); - current = new Entry ; - initEntry(); + ":" { + lineCount(); + g_specialBlock = TRUE; // expecting a docstring - BEGIN( Body ); - } + BEGIN( FunctionBody ); + } {PARAMNONEMPTY} { // Default rule inside arguments. } } -<Body>{ - "def"{BB} { - lineCount(); - current->fileName = yyFileName; - current->startLine = yyLineNr; - current->bodyLine = yyLineNr; - current->section = Entry::FUNCTION_SEC; - current->protection = protection = Public; - current->objc = FALSE; - current->virt = Normal; - current->stat = FALSE; - current->mtype = mtype = Method; - current->type.resize(0); - current->name.resize(0); - current->args.resize(0); - current->argList->clear(); +<ClassBody>{ + \n/{IDENTIFIER}{BB} { // new def at indent 0 + yyLineNr++; + endOfDef(); + BEGIN(Search); + } + ^{BB}\n { // skip empty line + current->program+=yytext; + yyLineNr++; + } + <<EOF>> { + endOfDef(); + yyterminate(); + } + ^{BB} { // something at indent >0 + if (computeIndent(yytext)<=g_indent) + // jumped out of the class + { + endOfDef(); + g_indent=computeIndent(yytext); + BEGIN(Search); + } + else + { + current->program+=yytext; + } + } + "'" { // start of a single quoted string + current->program+=*yytext; + g_stringContext=YY_START; + g_specialBlock = FALSE; + g_copyString=¤t->program; + BEGIN( SingleQuoteString ); + } + "\"" { // start of a double quoted string + current->program+=*yytext; + g_stringContext=YY_START; + g_specialBlock = FALSE; + g_copyString=¤t->program; + BEGIN( DoubleQuoteString ); + } + [^ \t\n#'"]+ { // non-special stuff + current->program+=yytext; + g_specialBlock = FALSE; + } + ^{POUNDCOMMENT} { // normal comment + current->program+=yytext; + } + {NEWLINE} { + current->program+=*yytext; + yyLineNr++; + } + . { // any character + g_specialBlock = FALSE; + current->program+=*yytext; + } + {TRIDOUBLEQUOTE} { // start of a comment block + current->program+=yytext; + initTriDoubleQuoteBlock(); + BEGIN(TripleComment); + } + + {TRISINGLEQUOTE} { // start of a comment block + current->program+=yytext; + initTriSingleQuoteBlock(); + BEGIN(TripleComment); + } - // If this function has slipped out - // of the parent scope, jump out. - if ( g_indent == 0 || g_indent < class_indent ) +} + +<ClassDec>{IDENTIFIER} { + if (current->type.isEmpty()) { - // printf("Function has slipped out of scope! (%d < %d)", g_indent, class_indent); + current->type = "class"; + } - class_indent = 0; + current->section = Entry::CLASS_SEC; + current->name = yytext; - if (current_root->parent) - { - current_root = current_root->parent; - } - else - { - // This is bad!!! - // printf("Warning: using global root because pointer to parent was lost\n"); - current_root = global_root; - } + // prepend scope in case of nested classes + if (current_root->section&Entry::SCOPE_MASK) + { + current->name.prepend(current_root->name+"::"); + } + + current->name = current->name.stripWhiteSpace(); + current->fileName = yyFileName; + docBlockContext = YY_START; + docBlockInBody = FALSE; + docBlockJavaStyle = FALSE; + docBlock.resize(0); - } + BEGIN(ClassInheritance); + } - BEGIN( FunctionDec ); +<ClassInheritance>{ + ({BB}|[(,)]) { // syntactic sugar for the list } + ":" { // begin of the class definition + g_specialBlock = TRUE; // expecting a docstring + BEGIN(ClassCaptureIndent); + } - "class"{BB} { - lineCount() ; - current->section = Entry::CLASS_SEC; - current->argList->clear(); - current->type += "class" ; - current->fileName = yyFileName; - current->startLine = yyLineNr; - current->bodyLine = yyLineNr; + {IDENTIFIER} { + current->extends->append( + new BaseInfo(yytext,Public,Normal) + ); + //Has base class-do stuff + } +} - // Reset scope - new class found. - // (nested classes not supported) - classKeywordIndent = g_indent; - current_root = global_root; - BEGIN( ClassDec ) ; - } +<ClassCaptureIndent>{ + "\n"|({BB}"\n") { + // Blankline - ignore, keep looking for indentation. + lineCount(); + } + + {TRIDOUBLEQUOTE} { // start of a comment block + initTriDoubleQuoteBlock(); + BEGIN(TripleComment); + } + + {TRISINGLEQUOTE} { // start of a comment block + initTriSingleQuoteBlock(); + BEGIN(TripleComment); + } + + ^{BB} { + // Remember indentation level for later funcs + current->program=yytext; + current->startLine = yyLineNr; + //printf("current->program=[%s]\n",current->program.data()); + BEGIN( ClassBody ); + } + + ""/({NONEMPTY}|{EXPCHAR}) { + + // Just pushback an empty class, and + // resume parsing the body. + newEntry(); + + // printf("Failed to find indent - skipping!"); + BEGIN( Search ); + } +} + - ^{BB} { // This is for capturing the current indentation - // of the current line. - g_indent = yyleng; +<VariableDec>{ + "=" { // the assignment operator + } + {B} { // spaces + } + {INTNUMBER} { // integer value + current->type = "int"; + current->initializer = yytext; + BEGIN(VariableEnd); + } + {FLOATNUMBER} { // floating point value + current->type = "float"; + current->initializer = yytext; + BEGIN(VariableEnd); + } + {STRINGPREFIX}?"'" { // string + current->type = "string"; + current->initializer = yytext; + g_copyString=¤t->initializer; + g_stringContext=VariableEnd; + BEGIN( SingleQuoteString ); + } + {STRINGPREFIX}?"\"" { // string + current->type = "string"; + current->initializer = yytext; + g_copyString=¤t->initializer; + g_stringContext=VariableEnd; + BEGIN( DoubleQuoteString ); + } + {TRIDOUBLEQUOTE} { // start of a comment block + current->type = "string"; + g_doubleQuote=TRUE; + g_copyString=¤t->initializer; + g_stringContext=VariableEnd; + BEGIN(TripleString); } - [^\n] { - // This is the major default - // that should catch everything - // else in Body. + {TRISINGLEQUOTE} { // start of a comment block + current->type = "string"; + g_doubleQuote=FALSE; + g_copyString=¤t->initializer; + g_stringContext=VariableEnd; + BEGIN(TripleString); + } + "(" { // typle + current->type = "tuple"; + current->initializer+=*yytext; + g_atomStart='('; + g_atomEnd=')'; + g_atomCount=1; + BEGIN( VariableAtom ); + } + "[" { // list + current->type = "list"; + current->initializer+=*yytext; + g_atomStart='['; + g_atomEnd=']'; + g_atomCount=1; + BEGIN( VariableAtom ); } + "{" { // dictionary + current->type = "dictionary"; + current->initializer+=*yytext; + g_atomStart='{'; + g_atomEnd='}'; + g_atomCount=1; + BEGIN( VariableAtom ); + } + "#".* { // comment + BEGIN( VariableEnd ); + } + . { + current->initializer+=*yytext; + } + \n { + unput('\n'); + BEGIN( VariableEnd ); + } +} - {NEWLINE}+ { - lineCount(); - g_indent = 0; +<VariableAtom>{ + [\(\[\{] { + current->initializer+=*yytext; + if (g_atomStart==*yytext) + { + g_atomCount++; + } + } + [\)\]\}] { + current->initializer+=*yytext; + if (g_atomEnd==*yytext) + { + g_atomCount--; + } + if (g_atomCount==0) + { + BEGIN(VariableEnd); + } } + {IDENTIFIER} { + current->initializer+=yytext; + } + . { + current->initializer+=*yytext; + } + \n { + current->initializer+=*yytext; + yyLineNr++; + } + } -<MultiDoubleComment>{ - {TRIDOUBLEQUOTE} { - if (g_doubleQuote) - { - if (g_specialBlock) - { - handleCommentBlock(docBlock, FALSE); - } - else - { - docBlock.resize(0); - } - BEGIN(docBlockContext); - } - else - { - docBlock += yytext; - } - } +<VariableEnd>{ + \n { + yyLineNr++; + newVariable(); + BEGIN(Search); + } + . { + unput(*yytext); + newVariable(); + BEGIN(Search); + } + <<EOF>> { yyterminate(); + newEntry(); + } +} - {TRISINGLEQUOTE} { - if (!g_doubleQuote) +<TripleComment>{ + {TRIDOUBLEQUOTE} | + {TRISINGLEQUOTE} { + //printf("Expected module block %d special=%d\n",g_expectModuleDocs,g_specialBlock); + if (g_doubleQuote==(yytext[0]=='"')) { - if (g_specialBlock) + if (g_specialBlock || g_expectModuleDocs) { - handleCommentBlock(docBlock, FALSE); + QCString actualDoc=docBlock; + actualDoc.prepend("\\verbatim "); + actualDoc.append("\\endverbatim "); + if (g_expectModuleDocs) + { + actualDoc.prepend("\\file \\_linebr "); + } + handleCommentBlock(actualDoc, FALSE); } - else + g_expectModuleDocs=FALSE; + if (docBlockContext==ClassBody) { - docBlock.resize(0); + current->program+=docBlock; + current->program+=yytext; } BEGIN(docBlockContext); } @@ -576,10 +1010,18 @@ STARTDOCSYMS "##" } } + ({LONGSTRINGBLOCK}) { lineCount(); docBlock += yytext; } + \n { + yyLineNr++; + docBlock += yytext; + } + . { + docBlock += yytext; + } } <SpecialComment>{ @@ -604,170 +1046,98 @@ STARTDOCSYMS "##" } } - /* ------------ Class rules -------------- */ - -<ClassDec>{IDENTIFIER} { - if (current->type.isEmpty()) - { - current->type = "class"; - } - - current->section = Entry::CLASS_SEC; - current->name = yytext; - current->name = current->name.stripWhiteSpace(); - current->fileName = yyFileName; - docBlockContext = YY_START; - docBlockInBody = FALSE; - docBlockJavaStyle = FALSE; - docBlock.resize(0); - - // Setting indentation to 0; this totally - // totally disallows nested classes. - // This is okay for now. - class_indent = 0; - - BEGIN(ClassInheritance); - } - -<ClassInheritance>{ - ({BB}|[(,)]) { - } - - ":" { - //BEGIN(TryClassDocString); - BEGIN(ClassCaptureIndent); - } - - - {IDENTIFIER} { - current->extends->append( - new BaseInfo(yytext,Public,Normal) - ); - //Has base class-do stuff - } +<SingleQuoteString>{ + \\{B}\n { // line continuation + addToString(yytext); + yyLineNr++; + } + \\. { // espaced char + addToString(yytext); + } + "\"\"\"" { // tripple double quotes + addToString(yytext); + } + "'" { // end of the string + addToString(yytext); + BEGIN(g_stringContext); + } + [^"'\n\\]+ { // normal chars + addToString(yytext); + } + . { // normal char + addToString(yytext); + } } - -<ClassCaptureIndent>{ - "\n"|({BB}"\n") { - // Blankline - ignore, keep looking for indentation. - lineCount(); +<DoubleQuoteString>{ + \\{B}\n { // line continuation + addToString(yytext); + yyLineNr++; } - - {BB}/({NONEMPTY}|{EXPCHAR}) { - // Indentation level found! - // Pushback the class, and - // try to take over as the current root. - - // Add to tree - current_root->addSubEntry(current); - - if (yyleng >= classKeywordIndent) - { - // Take over the parent if this indentation - // is greater than the indentation - // of where the class started. - current->parent = current_root; - current_root = current; - previous = 0; - class_indent = yyleng; - - // printf("Found indent of %d on line %d, using it.\n", class_indent, yyLineNr); - } - else - { - // Otherwise, don't push deeper; - // this class's scope never started - // properly. - previous = current; - current->endBodyLine = yyLineNr; - // printf("Found indent, but its too small (%d < %d)", yyleng, classKeywordIndent); - } - - // Re-initialize current - current = new Entry ; - initEntry(); - - // Remember indentation level for later funcs - g_indent = yyleng; - BEGIN( Body ); + \\. { // espaced char + addToString(yytext); } - - ""/({NONEMPTY}|{EXPCHAR}) { - // Default rule; this is a syntax error - // (no indentation defined by user). - class_indent = 0; - - // Just pushback an empty class, and - // resume parsing the body. - previous = current; - current_root->addSubEntry(current); - current = new Entry ; - initEntry(); - - // printf("Failed to find indent - skipping!"); - BEGIN( Body ); + "'''" { // tripple single quotes + addToString(yytext); + } + "\"" { // end of the string + addToString(yytext); + BEGIN(g_stringContext); + } + [^"'\n\\]+ { // normal chars + addToString(yytext); + } + . { // normal char + addToString(yytext); } } +<TripleString>{ + {TRIDOUBLEQUOTE} | + {TRISINGLEQUOTE} { + *g_copyString += yytext; + //printf("Expected module block %d special=%d\n",g_expectModuleDocs,g_specialBlock); + if (g_doubleQuote==(yytext[0]=='"')) + { + BEGIN(docBlockContext); + } + } - /* ------------ End rules -------------- */ - -<*>{TRIDOUBLEQUOTE}("!")? { // start of a comment block - lineCount(); - docBlockContext = YY_START; - docBlockInBody = FALSE; - docBlockJavaStyle = FALSE; - docBlock.resize(0); - g_doubleQuote = TRUE; - g_specialBlock = yytext[yyleng-1]=='!'; - startCommentBlock(FALSE); - BEGIN(MultiDoubleComment); - } - -<*>{TRISINGLEQUOTE}("!"?) { - lineCount(); - docBlockContext = YY_START; - docBlockInBody = FALSE; - docBlockJavaStyle = FALSE; - docBlock.resize(0); - g_doubleQuote = FALSE; - g_specialBlock = yytext[yyleng-1]=='!'; - startCommentBlock(FALSE); - BEGIN(MultiDoubleComment); - } - -<*>{STARTDOCSYMS} { - docBlockContext = YY_START; - docBlockInBody = FALSE; - docBlockJavaStyle = TRUE; - docBrief = TRUE; - docBlock.resize(0); - startCommentBlock(TRUE); - BEGIN(SpecialComment); - } + ({LONGSTRINGBLOCK}) { + lineCount(); + *g_copyString += yytext; + } + \n { + yyLineNr++; + *g_copyString += yytext; + } + . { + *g_copyString += *yytext; + } +} + /* ------------ End rules -------------- */ + /* <*>({NONEMPTY}|{EXPCHAR}|{BB}) { // This should go one character at a time. // printf("[pyscanner] '%s' [ state %d ] [line %d] no match\n", // yytext, YY_START, yyLineNr); } + */ <*>{NEWLINE} { //printf("[pyscanner] %d NEWLINE [line %d] no match\n", // YY_START, yyLineNr); lineCount(); - BEGIN(Body); } <*>. { //printf("[pyscanner] '%s' [ state %d ] [line %d] no match\n", // yytext, YY_START, yyLineNr); - BEGIN(Body); } @@ -787,47 +1157,24 @@ static void parseCompounds(Entry *rt) //printf("-- %s ---------\n%s\n---------------\n", // ce->name.data(),ce->program.data()); // init scanner state - padCount=0; - depthIf = 0; inputString = ce->program; - lastDefGroup.groupname.resize(0); inputPosition = 0; pyscanYYrestart( pyscanYYin ) ; - - BEGIN( Body ) ; - + BEGIN( Search ) ; current_root = ce ; yyFileName = ce->fileName; - //setContext(); yyLineNr = ce->startLine ; - //insideObjC = ce->objc; - //printf("---> Inner block starts at line %d objC=%d\n",yyLineNr,insideObjC); - //current->reset(); if (current) delete current; current = new Entry; - gstat = FALSE; - int ni=ce->name.findRev("::"); if (ni==-1) ni=0; else ni+=2; - // set default protection based on the compound type - if ( ce->section==Entry::CLASS_SEC ) // class - { - current->protection = protection = Public; - } - mtype = Method; - virt = Normal; - //printf("name=%s current->stat=%d gstat=%d\n",ce->name.data(),current->stat,gstat); - memberGroupId = DOX_NOGROUP; - memberGroupRelates.resize(0); - memberGroupInside.resize(0); + groupEnterCompound(yyFileName,yyLineNr,ce->name); pyscanYYlex() ; delete current; current=0; ce->program.resize(0); - if (depthIf>0) - { - warn(yyFileName,yyLineNr,"Documentation block ended in the middle of a conditional section!"); - } + groupLeaveCompound(yyFileName,yyLineNr,ce->name); + } parseCompounds(ce); } @@ -835,6 +1182,7 @@ static void parseCompounds(Entry *rt) //---------------------------------------------------------------------------- + static void parseMain(const char *fileName,const char *fileBuf,Entry *rt) { initParser(); @@ -842,15 +1190,16 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt) inputString = fileBuf; inputPosition = 0; - anonCount = 0; - depthIf = 0; protection = Public; mtype = Method; gstat = FALSE; virt = Normal; current_root = rt; + g_expectModuleDocs = TRUE; + g_specialBlock = FALSE; + g_insideConstructor = FALSE; + - global_root = rt; inputFile.setName(fileName); if (inputFile.open(IO_ReadOnly)) { @@ -859,39 +1208,45 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt) //setContext(); msg("Parsing file %s...\n",yyFileName.data()); - current_root = rt ; - initParser(); - current = new Entry; - int sec=guessSection(yyFileName); - if (sec) + QFileInfo fi(fileName); + QCString moduleScope = findPackageScope(fileName); + if (!moduleScope.isEmpty()) { - current->name = yyFileName; - current->section = sec; - current_root->addSubEntry(current); - current = new Entry; + moduleScope+="::"; } + moduleScope+=fi.baseName(); + current = new Entry; + current->name = moduleScope; + current->section = Entry::NAMESPACE_SEC; + current->type = "namespace"; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + rt->addSubEntry(current); + + current_root = current ; + initParser(); + current = new Entry; // Set the python flags //current_root->python = TRUE; //current->python = TRUE; + groupEnterFile(yyFileName,yyLineNr); + current->reset(); pyscanYYrestart( pyscanYYin ); - BEGIN( Body ); - + BEGIN( Search ); pyscanYYlex(); - //call ast visitor - if (depthIf>0) - { - warn(yyFileName,yyLineNr,"Documentation block ended in the middle of a conditional section!"); - } - rt->program.resize(0); + groupLeaveFile(yyFileName,yyLineNr); + + current_root->program.resize(0); delete current; current=0; - parseCompounds(rt); + parseCompounds(current_root); inputFile.close(); } @@ -904,6 +1259,10 @@ static void parsePrototype(const QCString &text) { //printf("**** parsePrototype(%s) begin\n",text.data()); + g_expectModuleDocs = FALSE; + g_specialBlock = FALSE; + g_insideConstructor = FALSE; + const char *orgInputString; int orgInputPosition; YY_BUFFER_STATE orgState; @@ -919,7 +1278,7 @@ static void parsePrototype(const QCString &text) inputPosition = 0; pyscanYYrestart( pyscanYYin ); - BEGIN( Body ); + BEGIN( Search ); pyscanYYlex(); @@ -978,17 +1337,6 @@ void PythonLanguageScanner::resetCodeParserState() ::resetPythonCodeParserState(); } -void PythonLanguageScanner::handleGroupStartCommand(const char * /*header*/) -{ - -} - -void PythonLanguageScanner::handleGroupEndCommand() -{ - -} - - //---------------------------------------------------------------------------- #if !defined(YY_FLEX_SUBMINOR_VERSION) diff --git a/src/scanner.h b/src/scanner.h index 8432f6f..2c3ac6a 100644 --- a/src/scanner.h +++ b/src/scanner.h @@ -46,8 +46,6 @@ class CLanguageScanner : public ParserInterface ); void resetCodeParserState(); void parsePrototype(const char *text); - void handleGroupStartCommand(const char *header); - void handleGroupEndCommand(); }; #endif diff --git a/src/scanner.l b/src/scanner.l index 810a79b..6aa138d 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -85,16 +85,15 @@ static Entry* tempEntry = 0 ; static int yyLineNr = 1 ; static int anonCount = 0 ; static QCString yyFileName; -static int lastMemberGroupLine; static MethodTypes mtype; static bool gstat; static bool removeSlashes; static Specifier virt; static Specifier baseVirt; static QCString msType,msName,msArgs; -static int memberGroupId = DOX_NOGROUP; -static QCString memberGroupHeader; -static QCString memberGroupDocs; +//static int memberGroupId = DOX_NOGROUP; +//static QCString memberGroupHeader; +//static QCString memberGroupDocs; static bool isTypedef; static int tmpDocType; static QCString sectionLabel; @@ -131,7 +130,6 @@ static QCString *pCopyCurlyString; static QCString *pCopyQuotedString; static QCString *pSkipVerbString; static QStack<Grouping> autoGroupStack; -static Grouping lastDefGroup( "", Grouping::GROUPING_LOWEST ); static bool insideFormula; static bool insideTryBlock=FALSE; @@ -163,8 +161,8 @@ static char docBlockTerm; //----------------------------------------------------------------------------- // forward declarations -static void handleGroupStartCommand(const char *header); -static void handleGroupEndCommand(); +//static void handleGroupStartCommand(const char *header); +//static void handleGroupEndCommand(); //----------------------------------------------------------------------------- @@ -179,9 +177,9 @@ static void initParser() sharpCount = 0; roundCount = 0; curlyCount = 0; - memberGroupId = DOX_NOGROUP; - memberGroupRelates.resize(0); - memberGroupInside.resize(0); + //memberGroupId = DOX_NOGROUP; + //memberGroupRelates.resize(0); + //memberGroupInside.resize(0); mtype = Method; gstat = FALSE; virt = Normal; @@ -190,7 +188,6 @@ static void initParser() autoGroupStack.clear(); insideTryBlock = FALSE; autoGroupStack.setAutoDelete(TRUE); - lastDefGroup.groupname.resize(0); insideFormula = FALSE; insideCode=FALSE; previous = 0; @@ -206,53 +203,54 @@ static void initEntry() current->mtype = mtype; current->virt = virt; current->stat = gstat; - current->mGrpId = memberGroupId; - current->relates = memberGroupRelates.copy(); - current->inside = memberGroupInside.copy(); + //current->mGrpId = memberGroupId; + //current->relates = memberGroupRelates; + current->inside = memberGroupInside; current->objc = insideObjC; - if (!autoGroupStack.isEmpty()) - { - //printf("Appending group %s\n",autoGroupStack.top()->groupname.data()); - current->groups->append(new Grouping(*autoGroupStack.top())); - } + //if (!autoGroupStack.isEmpty()) + //{ + // //printf("Appending group %s\n",autoGroupStack.top()->groupname.data()); + // current->groups->append(new Grouping(*autoGroupStack.top())); + //} + initGroupInfo(current); } //----------------------------------------------------------------------------- -/// remove any automatic grouping and add new one (if given) -static void setCurrentGroup( QCString *newgroup, Grouping::GroupPri_t pri ) -{ - /* remove auto group name from current entry and discard it */ - Grouping *g = current->groups->first(); - int i=0; - while (g) - { - if (g->pri <= Grouping::GROUPING_AUTO_DEF) - { - current->groups->remove(i); - i--; - } - g=current->groups->next(); - i++; - } - - /* use new group name instead? */ - if ( newgroup ) - { - current->groups->append(new Grouping(*newgroup, pri)); - } -} - -static int newMemberGroupId() -{ - static int curGroupId=0; - return curGroupId++; -} - +///// remove any automatic grouping and add new one (if given) +//static void setCurrentGroup( QCString *newgroup, Grouping::GroupPri_t pri ) +//{ +// /* remove auto group name from current entry and discard it */ +// Grouping *g = current->groups->first(); +// int i=0; +// while (g) +// { +// if (g->pri <= Grouping::GROUPING_AUTO_DEF) +// { +// current->groups->remove(i); +// i--; +// } +// g=current->groups->next(); +// i++; +// } +// +// /* use new group name instead? */ +// if ( newgroup ) +// { +// current->groups->append(new Grouping(*newgroup, pri)); +// } +//} +// +//static int newMemberGroupId() +//{ +// static int curGroupId=0; +// return curGroupId++; +//} +// // forward declarations -static void startGroupInDoc(); -static void endGroup(); +//static void startGroupInDoc(); +//static void endGroup(); //----------------------------------------------------------------------------- @@ -296,27 +294,6 @@ static QCString stripQuotes(const char *s) //----------------------------------------------------------------- -static void addMemberGroupDocs() -{ - memberGroupDocs=current->brief.stripWhiteSpace(); - current->doc = stripLeadingAndTrailingEmptyLines(current->doc); - if (!memberGroupDocs.isEmpty() && !current->doc.isEmpty()) - { - memberGroupDocs+="\n\n"; - } - memberGroupDocs+=current->doc; - MemberGroupInfo *info=Doxygen::memGrpInfoDict.find(memberGroupId); - if (info) - { - info->doc = memberGroupDocs; - info->docFile = yyFileName; - } - current->doc.resize(0); - current->brief.resize(0); -} - -//----------------------------------------------------------------- - static void startCommentBlock(bool); static void handleCommentBlock(const QCString &doc,bool brief); //----------------------------------------------------------------- @@ -1836,13 +1813,23 @@ IDLATTR ("["[^\]]*"]"){BN}* } <FindMembers,FindFields>("//"([!/]?){B}*{CMD}"{")|("/*"([!*]?){B}*{CMD}"{") { - Entry *tmp = current; - if (previous) + //Entry *tmp = current; + //if (previous) + //{ + // current = previous; + //} + //handleGroupStartCommand(current->name); + if (previous && previous->section==Entry::GROUPDOC_SEC) { - current = previous; + // link open command to the group defined in the previous entry + openGroup(previous,yyFileName,yyLineNr); } - handleGroupStartCommand(current->name); - current = tmp; + else + { + // link open command to the current entry + openGroup(current,yyFileName,yyLineNr); + } + //current = tmp; initEntry(); if (yytext[1]=='/') { @@ -1882,7 +1869,8 @@ IDLATTR ("["[^\]]*"]"){BN}* } } <FindMembers,FindFields,ReadInitializer>"//"([!/]?){B}*{CMD}"}".*|"/*"([!*]?){B}*{CMD}"}".*"*/" { - handleGroupEndCommand(); + //handleGroupEndCommand(); + closeGroup(current,yyFileName,yyLineNr); } <FindMembers>"=" { current->bodyLine = yyLineNr; @@ -4230,8 +4218,18 @@ static void startCommentBlock(bool brief) //---------------------------------------------------------------------------- +static void newEntry() +{ + current_root->addSubEntry(current); + previous = current; + current = new Entry ; + initEntry(); +} + static void handleCommentBlock(const QCString &doc,bool brief) { + int position=0; + bool needsEntry; if (docBlockInBody) { if (previous==0) @@ -4244,25 +4242,27 @@ static void handleCommentBlock(const QCString &doc,bool brief) previous->doc=previous->doc.stripWhiteSpace()+"\n\n"; } } - if (parseCommentBlock( + //printf("parseCommentBlock [%s]\n",doc.data()); + while (parseCommentBlock( g_thisParser, docBlockInBody ? previous : current, - doc, // text + doc, // text yyFileName, // file brief ? current->briefLine : current->docLine, // line of block start docBlockInBody ? FALSE : brief, docBlockInBody ? FALSE : docBlockJavaStyle, - protection) - ) // need to start a new entry + protection, + position, + needsEntry + ) + ) { - if (current->section==Entry::MEMBERGRP_SEC) - { - addMemberGroupDocs(); - } - current_root->addSubEntry(current); - previous = current; - current = new Entry ; - initEntry(); + //printf("parseCommentBlock position=%d [%s]\n",position,doc.data()+position); + if (needsEntry) newEntry(); + } + if (needsEntry) + { + newEntry(); } exit: @@ -4275,83 +4275,82 @@ exit: //---------------------------------------------------------------------------- -static void startGroupInDoc() -{ - if (current->section==Entry::GROUPDOC_SEC ) /* scope for a non-member group: @defgroup */ - { - autoGroupStack.push(new Grouping(current->name, - current->groupingPri() - )); - } - else /* if (current->section == Entry::MEMBERGRP_SEC) scope for a member group: @name */ - { - if (memberGroupId!=DOX_NOGROUP) - { - warn(yyFileName,yyLineNr,"Warning: member groups cannot be nested. Ending current group!\n"); - endGroup(); - } - memberGroupId = newMemberGroupId(); - MemberGroupInfo *info = new MemberGroupInfo; - if (current->section == Entry::MEMBERGRP_SEC) - { - info->header = memberGroupHeader.stripWhiteSpace(); - } - Doxygen::memGrpInfoDict.insert(memberGroupId,info); - memberGroupRelates = current->relates.copy(); - memberGroupInside = current->inside.copy(); - current->mGrpId = memberGroupId; - lastMemberGroupLine = yyLineNr; - } -} - -//---------------------------------------------------------------------------- - -static void endGroup() -{ - if (memberGroupId!=DOX_NOGROUP) // end of member group - { - //Doxygen::memberDocDict.insert(memberGroupId, - // new QCString(memberGroupDocs) - // ); - MemberGroupInfo *info=Doxygen::memGrpInfoDict.find(memberGroupId); - if (info) - { - info->doc = memberGroupDocs; - info->docFile = yyFileName; - } - memberGroupId=DOX_NOGROUP; - memberGroupRelates.resize(0); - memberGroupInside.resize(0); - if (YY_START!=ReadInitializer) - { - current->mGrpId=DOX_NOGROUP; - current->relates.resize(0); - } - memberGroupDocs.resize(0); - } - else if (!autoGroupStack.isEmpty()) // end of group - { - Grouping *current = autoGroupStack.pop(); - Grouping *parent = autoGroupStack.top(); - if( parent ) { - setCurrentGroup( &parent->groupname, parent->pri ); - } else { - setCurrentGroup( 0, Grouping::GROUPING_LOWEST ); - } - delete current; - } -} - -//---------------------------------------------------------------------------- - -static void forceEndGroup() -{ - while (memberGroupId!=DOX_NOGROUP || !autoGroupStack.isEmpty()) - { - //printf("forceEndGroup ends group %d\n",memberGroupId); - endGroup(); - } -} +//static void startGroupInDoc() +//{ +// if (current->section==Entry::GROUPDOC_SEC ) /* scope for a non-member group: @defgroup */ +// { +// autoGroupStack.push(new Grouping(current->name, +// current->groupingPri() +// )); +// } +// else /* if (current->section == Entry::MEMBERGRP_SEC) scope for a member group: @name */ +// { +// if (memberGroupId!=DOX_NOGROUP) +// { +// warn(yyFileName,yyLineNr,"Warning: member groups cannot be nested. Ending current group!\n"); +// endGroup(); +// } +// memberGroupId = newMemberGroupId(); +// MemberGroupInfo *info = new MemberGroupInfo; +// if (current->section == Entry::MEMBERGRP_SEC) +// { +// info->header = memberGroupHeader.stripWhiteSpace(); +// } +// Doxygen::memGrpInfoDict.insert(memberGroupId,info); +// memberGroupRelates = current->relates; +// memberGroupInside = current->inside; +// current->mGrpId = memberGroupId; +// } +//} +// +////---------------------------------------------------------------------------- +// +//static void endGroup() +//{ +// if (memberGroupId!=DOX_NOGROUP) // end of member group +// { +// //Doxygen::memberDocDict.insert(memberGroupId, +// // new QCString(memberGroupDocs) +// // ); +// MemberGroupInfo *info=Doxygen::memGrpInfoDict.find(memberGroupId); +// if (info) +// { +// info->doc = memberGroupDocs; +// info->docFile = yyFileName; +// } +// memberGroupId=DOX_NOGROUP; +// memberGroupRelates.resize(0); +// memberGroupInside.resize(0); +// if (YY_START!=ReadInitializer) +// { +// current->mGrpId=DOX_NOGROUP; +// current->relates.resize(0); +// } +// memberGroupDocs.resize(0); +// } +// else if (!autoGroupStack.isEmpty()) // end of group +// { +// Grouping *current = autoGroupStack.pop(); +// Grouping *parent = autoGroupStack.top(); +// if( parent ) { +// setCurrentGroup( &parent->groupname, parent->pri ); +// } else { +// setCurrentGroup( 0, Grouping::GROUPING_LOWEST ); +// } +// delete current; +// } +//} +// +////---------------------------------------------------------------------------- +// +//static void forceEndGroup() +//{ +// while (memberGroupId!=DOX_NOGROUP || !autoGroupStack.isEmpty()) +// { +// //printf("forceEndGroup ends group %d\n",memberGroupId); +// endGroup(); +// } +//} //---------------------------------------------------------------------------- @@ -4371,7 +4370,6 @@ static void parseCompounds(Entry *rt) padCount=0; depthIf = 0; inputString = ce->program; - lastDefGroup.groupname.resize(0); inputPosition = 0; scanYYrestart( scanYYin ) ; if (ce->section==Entry::ENUM_SEC) @@ -4434,12 +4432,16 @@ static void parseCompounds(Entry *rt) virt = Normal; //printf("name=%s current->stat=%d gstat=%d\n",ce->name.data(),current->stat,gstat); - memberGroupId = DOX_NOGROUP; - memberGroupRelates.resize(0); - memberGroupInside.resize(0); + //memberGroupId = DOX_NOGROUP; + //memberGroupRelates.resize(0); + //memberGroupInside.resize(0); + groupEnterCompound(yyFileName,yyLineNr,ce->name); scanYYlex() ; - forceEndGroup(); + //forceEndGroup(); + + groupLeaveCompound(yyFileName,yyLineNr,ce->name); + delete current; current=0; ce->program.resize(0); @@ -4482,6 +4484,7 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt) current_root = rt ; initParser(); + groupEnterFile(yyFileName,yyLineNr); current = new Entry; int sec=guessSection(yyFileName); if (sec) @@ -4509,7 +4512,8 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt) warn(yyFileName,yyLineNr,"File ended in the middle of a comment block! Perhaps a missing \\endcode?"); } - forceEndGroup(); + //forceEndGroup(); + groupLeaveFile(yyFileName,yyLineNr); if (depthIf>0) { @@ -4569,17 +4573,17 @@ static void parsePrototype(const QCString &text) //printf("**** parsePrototype end\n"); } -static void handleGroupStartCommand(const char *header) -{ - memberGroupHeader=header; - startGroupInDoc(); -} - -static void handleGroupEndCommand() -{ - endGroup(); - previous=0; -} +//static void handleGroupStartCommand(const char *header) +//{ +// memberGroupHeader=header; +// startGroupInDoc(); +//} +// +//static void handleGroupEndCommand() +//{ +// endGroup(); +// previous=0; +//} //---------------------------------------------------------------------------- @@ -4624,15 +4628,6 @@ void CLanguageScanner::parsePrototype(const char *text) ::parsePrototype(text); } -void CLanguageScanner::handleGroupStartCommand(const char *header) -{ - ::handleGroupStartCommand(header); -} - -void CLanguageScanner::handleGroupEndCommand() -{ - ::handleGroupEndCommand(); -} //---------------------------------------------------------------------------- diff --git a/src/search.php b/src/search.php index b3ac0e6..b908125 100644 --- a/src/search.php +++ b/src/search.php @@ -292,6 +292,7 @@ function main() echo "</span>\n"; echo "</form>\n"; echo "</div>\n"; + echo "<div class=\"searchresults\">\n"; $results = array(); $requiredWords = array(); $forbiddenWords = array(); @@ -318,6 +319,7 @@ function main() sort_results($filteredDocs,$sorted); // report results to the user report_results($sorted); + echo "</div>\n"; fclose($file); } diff --git a/src/search_php.h b/src/search_php.h index 04c95fe..a31aed9 100644 --- a/src/search_php.h +++ b/src/search_php.h @@ -292,6 +292,7 @@ " echo \"</span>\\n\";\n" " echo \"</form>\\n\";\n" " echo \"</div>\\n\";\n" +" echo \"<div class=\\\"searchresults\\\">\\n\";\n" " $results = array();\n" " $requiredWords = array();\n" " $forbiddenWords = array();\n" @@ -318,6 +319,7 @@ " sort_results($filteredDocs,$sorted);\n" " // report results to the user\n" " report_results($sorted);\n" +" echo \"</div>\\n\";\n" " fclose($file);\n" "}\n" "\n" diff --git a/src/translator_adapter.h b/src/translator_adapter.h index fa6f8a2..8962e84 100644 --- a/src/translator_adapter.h +++ b/src/translator_adapter.h @@ -13,6 +13,7 @@ class TranslatorAdapterBase : public Translator { protected: + virtual ~TranslatorAdapterBase() {} TranslatorEnglish english; /*! An auxiliary inline method used by the updateNeededMessage() diff --git a/src/translator_en.h b/src/translator_en.h index fd9ea87..6f2c96c 100644 --- a/src/translator_en.h +++ b/src/translator_en.h @@ -42,6 +42,10 @@ */ class TranslatorEnglish : public Translator { + protected: + friend class TranslatorAdapterBase; + virtual ~TranslatorEnglish() {} + public: // --- Language control methods ------------------- diff --git a/src/util.cpp b/src/util.cpp index 881988e..a175db0 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -2705,7 +2705,7 @@ static QCString getCanonicalTypeForIdentifier( { QCString ts; result = resolveSymbolName(fs,defList->first(),ts); - *tSpec=""; + if (tSpec) *tSpec=""; } else if (!symName.isEmpty() && (defList=Doxygen::symbolMap->find(symName)) && @@ -2723,7 +2723,7 @@ static QCString getCanonicalTypeForIdentifier( if (!templSpec.isEmpty()) { cd = getResolvedClass(d,fs,word+templSpec,&mType,0,TRUE); - if (cd) *tSpec=""; + if (cd && tSpec) *tSpec=""; } if (cd==0) { @@ -2742,7 +2742,7 @@ static QCString getCanonicalTypeForIdentifier( { //result = cd->qualifiedNameWithTemplateParameters(); result = removeRedundantWhiteSpace(cd->qualifiedName()+templSpec); - if (cd->isTemplate()) + if (cd->isTemplate() && tSpec) { *tSpec=""; } @@ -57,6 +57,7 @@ class Definition; class TextGeneratorIntf { public: + virtual ~TextGeneratorIntf() {} virtual void writeString(const char *,bool) const = 0; virtual void writeBreak() const = 0; virtual void writeLink(const char *extRef,const char *file, @@ -67,6 +68,7 @@ class TextGeneratorIntf class TextGeneratorOLImpl : public TextGeneratorIntf { public: + virtual ~TextGeneratorOLImpl() {} TextGeneratorOLImpl(OutputDocInterface &od); void writeString(const char *s,bool keepSpaces) const; void writeBreak() const; |