diff options
author | dimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7> | 2005-07-07 20:16:18 (GMT) |
---|---|---|
committer | dimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7> | 2005-07-07 20:16:18 (GMT) |
commit | 6c5b1ce29dc2ed6a8fbf7e69b7d085bdb3e87647 (patch) | |
tree | 3b82721edc171f76f1a6712ff59e547a592aec23 | |
parent | f92ed7a658968bac5b777322fea4d7216e41b487 (diff) | |
download | Doxygen-6c5b1ce29dc2ed6a8fbf7e69b7d085bdb3e87647.zip Doxygen-6c5b1ce29dc2ed6a8fbf7e69b7d085bdb3e87647.tar.gz Doxygen-6c5b1ce29dc2ed6a8fbf7e69b7d085bdb3e87647.tar.bz2 |
Release-1.4.3-20050707
-rw-r--r-- | INSTALL | 4 | ||||
-rw-r--r-- | README | 4 | ||||
-rw-r--r-- | VERSION | 2 | ||||
-rwxr-xr-x | configure | 2 | ||||
-rw-r--r-- | doc/config.doc | 4 | ||||
-rw-r--r-- | doc/language.doc | 2 | ||||
-rw-r--r-- | doc/translator_report.txt | 2 | ||||
-rw-r--r-- | qtools/qdatetime.h | 1 | ||||
-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 |
29 files changed, 1593 insertions, 981 deletions
@@ -1,7 +1,7 @@ -DOXYGEN Version 1.4.3-20050623 +DOXYGEN Version 1.4.3-20050707 Please read the installation section of the manual (http://www.doxygen.org/install.html) for instructions. -------- -Dimitri van Heesch (23 June 2005) +Dimitri van Heesch (07 July 2005) @@ -1,4 +1,4 @@ -DOXYGEN Version 1.4.3_20050623 +DOXYGEN Version 1.4.3_20050707 Please read INSTALL for compilation instructions. @@ -17,4 +17,4 @@ to subscribe to the lists or to visit the archives. Enjoy, -Dimitri van Heesch (dimitri@stack.nl) (23 June 2005) +Dimitri van Heesch (dimitri@stack.nl) (07 July 2005) @@ -1 +1 @@ -1.4.3-20050623 +1.4.3-20050707 @@ -240,7 +240,7 @@ if test "$f_wizard" = YES; then if test -z "$QTDIR"; then echo " QTDIR environment variable not set!" echo -n " Checking for Qt..." - for d in /usr/lib/{qt-3.1,qt3,qt2,qt,qt*}; do + for d in /usr/{lib,share,qt}/{qt-3,qt3,qt,qt*,3}; do if test -d "$d/lib" -a -d "$d/include" -a -x "$d/bin/moc"; then QTDIR=$d fi diff --git a/doc/config.doc b/doc/config.doc index 9a16a7b..e29233e 100644 --- a/doc/config.doc +++ b/doc/config.doc @@ -800,6 +800,10 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" \c EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude certain files from those directories. + Note that the wildcards are matched against the file with absolute path, + so to exclude all test directories use the pattern + <code>*</code><code>/test/</code><code>*</code> + \anchor cfg_example_path <dt>\c EXAMPLE_PATH <dd> \addindex EXAMPLE_PATH diff --git a/doc/language.doc b/doc/language.doc index 4af2938..dea524e 100644 --- a/doc/language.doc +++ b/doc/language.doc @@ -23,7 +23,7 @@ text fragments, generated by doxygen, can be produced in languages other than English (the default). The output language is chosen through the configuration file (with default name and known as Doxyfile). -Currently (version 1.4.3), 31 languages +Currently (version 1.4.3-20050623), 31 languages are supported (sorted alphabetically): Afrikaans, Brazilian Portuguese, Catalan, Chinese, Chinese Traditional, Croatian, Czech, Danish, Dutch, English, Finnish, French, diff --git a/doc/translator_report.txt b/doc/translator_report.txt index c1957bc..4a82efe 100644 --- a/doc/translator_report.txt +++ b/doc/translator_report.txt @@ -1,4 +1,4 @@ -(1.4.3) +(1.4.3-20050623) Doxygen supports the following 31 languages (sorted alphabetically): diff --git a/qtools/qdatetime.h b/qtools/qdatetime.h index 2479dbf..2d5869c 100644 --- a/qtools/qdatetime.h +++ b/qtools/qdatetime.h @@ -52,6 +52,7 @@ class Q_EXPORT QDate public: QDate() { jd=0; } // set null date QDate( int y, int m, int d ); // set date + virtual ~QDate() {} bool isNull() const { return jd == 0; } bool isValid() const; // valid date 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; |