diff options
author | Dimitri van Heesch <dimitri@stack.nl> | 2010-09-20 18:19:55 (GMT) |
---|---|---|
committer | Dimitri van Heesch <dimitri@stack.nl> | 2010-09-20 18:19:55 (GMT) |
commit | 6dbef217c477d43fb61e90b429531ee109bf0e75 (patch) | |
tree | c3964e8a42bc4dfecf5a99d6de94650878e67a0f /src | |
parent | 20bc00a80ad6bcda730a1762c3700c8f63fa16eb (diff) | |
download | Doxygen-6dbef217c477d43fb61e90b429531ee109bf0e75.zip Doxygen-6dbef217c477d43fb61e90b429531ee109bf0e75.tar.gz Doxygen-6dbef217c477d43fb61e90b429531ee109bf0e75.tar.bz2 |
Release-1.7.1-20100920
Diffstat (limited to 'src')
42 files changed, 1022 insertions, 125 deletions
diff --git a/src/classdef.cpp b/src/classdef.cpp index 04f8934..557604f 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -1065,7 +1065,8 @@ void ClassDef::writeInheritanceGraph(OutputList &ol) bool renderDiagram = FALSE; - if (Config_getBool("HAVE_DOT") && Config_getBool("CLASS_DIAGRAMS")) + if (Config_getBool("HAVE_DOT") && + (Config_getBool("CLASS_DIAGRAMS") || Config_getBool("CLASS_GRAPH"))) // write class diagram using dot { DotClassGraph inheritanceGraph(this,DotNode::Inheritance); diff --git a/src/cmdmapper.cpp b/src/cmdmapper.cpp index 16e8a7a..1e5cc17 100644 --- a/src/cmdmapper.cpp +++ b/src/cmdmapper.cpp @@ -112,7 +112,8 @@ CommandMap cmdMap[] = { "endmanonly", CMD_ENDMANONLY }, { "includelineno", CMD_INCWITHLINES }, { "inheritdoc", CMD_INHERITDOC }, - { 0, 0 } + { "mscfile", CMD_MSCFILE }, + { 0, 0 }, }; //---------------------------------------------------------------------------- diff --git a/src/cmdmapper.h b/src/cmdmapper.h index 011ebad..1f4bd02 100644 --- a/src/cmdmapper.h +++ b/src/cmdmapper.h @@ -113,7 +113,8 @@ enum CommandType CMD_TPARAM = 79 | SIMPLESECT_BIT, CMD_COPYBRIEF = 80, CMD_COPYDETAILS = 81, - CMD_QUOTE = 82 + CMD_QUOTE = 82, + CMD_MSCFILE = 83 }; enum HtmlTagType @@ -2851,13 +2851,15 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} if (cd) { setClassScope(cd->name()); + g_scopeStack.push(SCOPEBLOCK); + DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n")); } - else + else { - setClassScope(g_realScope); + //setClassScope(g_realScope); + g_scopeStack.push(INNERBLOCK); + DBG_CTX((stderr,"** scope stack push INNERBLOCK\n")); } - DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n")); - g_scopeStack.push(SCOPEBLOCK); } else { @@ -3356,7 +3358,8 @@ void parseCCode(CodeOutputInterface &od,const char *className,const QCString &s, int startLine,int endLine,bool inlineFragment, MemberDef *memberDef,bool showLineNumbers) { - //printf("***parseCode() exBlock=%d exName=%s fd=%p\n",exBlock,exName,fd); + //printf("***parseCode() exBlock=%d exName=%s fd=%p className=%s\n", + // exBlock,exName,fd,className); if (s.isEmpty()) return; if (g_codeClassSDict==0) { @@ -3386,6 +3389,7 @@ void parseCCode(CodeOutputInterface &od,const char *className,const QCString &s, g_theCallContext.clear(); g_scopeStack.clear(); g_classScope = className; + //printf("parseCCode %s\n",className); g_exampleBlock = exBlock; g_exampleName = exName; g_sourceFileDef = fd; diff --git a/src/commentscan.l b/src/commentscan.l index 892ac71..d4f7f0e 100644 --- a/src/commentscan.l +++ b/src/commentscan.l @@ -1038,7 +1038,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" <Comment>^{B}*"."{B}*/\n { // explicit end autolist: e.g " ." addOutput(yytext); } -<Comment>("."+)[a-z_A-Z0-9] { // . at start or in the middle of a word, or ellipsis +<Comment>("."+)[a-z_A-Z0-9\)] { // . at start or in the middle of a word, or ellipsis addOutput(yytext); } <Comment>".\\"[ \t] { // . with escaped space. diff --git a/src/compound.xsd b/src/compound.xsd index 369e230..7f67a2c 100644 --- a/src/compound.xsd +++ b/src/compound.xsd @@ -577,6 +577,7 @@ <xsd:complexType name="docParamNameList"> <xsd:sequence> + <xsd:element name="parametertype" type="docParamType" minOccurs="0" maxOccurs="unbounded" /> <xsd:element name="parametername" type="docParamName" minOccurs="0" maxOccurs="unbounded" /> </xsd:sequence> </xsd:complexType> @@ -585,6 +586,12 @@ <xsd:sequence> <xsd:element name="ref" type="refTextType" minOccurs="0" maxOccurs="1" /> </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="docParamName" mixed="true"> + <xsd:sequence> + <xsd:element name="ref" type="refTextType" minOccurs="0" maxOccurs="1" /> + </xsd:sequence> <xsd:attribute name="direction" type="DoxParamDir" use="optional" /> </xsd:complexType> diff --git a/src/compound_xsd.h b/src/compound_xsd.h index fd92308..0404b78 100644 --- a/src/compound_xsd.h +++ b/src/compound_xsd.h @@ -577,6 +577,7 @@ "\n" " <xsd:complexType name=\"docParamNameList\">\n" " <xsd:sequence>\n" +" <xsd:element name=\"parametertype\" type=\"docParamType\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" " <xsd:element name=\"parametername\" type=\"docParamName\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" " </xsd:sequence>\n" " </xsd:complexType>\n" @@ -585,6 +586,12 @@ " <xsd:sequence>\n" " <xsd:element name=\"ref\" type=\"refTextType\" minOccurs=\"0\" maxOccurs=\"1\" />\n" " </xsd:sequence>\n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docParamName\" mixed=\"true\">\n" +" <xsd:sequence>\n" +" <xsd:element name=\"ref\" type=\"refTextType\" minOccurs=\"0\" maxOccurs=\"1\" />\n" +" </xsd:sequence>\n" " <xsd:attribute name=\"direction\" type=\"DoxParamDir\" use=\"optional\" />\n" " </xsd:complexType>\n" "\n" diff --git a/src/config.l b/src/config.l index b45097c..532b1c4 100644 --- a/src/config.l +++ b/src/config.l @@ -1084,7 +1084,7 @@ void Config::check() paperType=paperType.lower().stripWhiteSpace(); if (paperType.isEmpty()) { - paperType = "a4wide"; + paperType = "a4"; } if (paperType!="a4" && paperType!="a4wide" && paperType!="letter" && paperType!="legal" && paperType!="executive") diff --git a/src/config.xml b/src/config.xml index 17d3644..8919ab3 100644 --- a/src/config.xml +++ b/src/config.xml @@ -290,7 +290,7 @@ doxygen to be busy swapping symbols to and from disk most of the time causing a significant performance penality. If the system has enough physical memory increasing the cache will improve the performance by keeping more symbols in memory. Note that the value works on -a logarithmic scale so increasing the size by one will rougly double the +a logarithmic scale so increasing the size by one will roughly double the memory usage. The cache size is given by this formula: 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, corresponding to a cache size of 2^16 = 65536 symbols @@ -514,7 +514,7 @@ parameters in a documented function, or documenting parameters that don't exist or using markup commands wrongly. ' defval='1'/> <option type='bool' id='WARN_NO_PARAMDOC' docs=' -The WARN_NO_PARAMDOC option can be abled to get warnings for +The WARN_NO_PARAMDOC option can be enabled to get warnings for functions that are documented, but have no documentation for their parameters or return value. If set to NO (the default) doxygen will only warn about wrong or incomplete parameter documentation, but not about the absence of @@ -999,7 +999,7 @@ implemented using a PHP enabled web server instead of at the web client using Javascript. Doxygen will generate the search PHP script and index file to put on the web server. The advantage of the server based approach is that it scales better to large projects and allows -full text search. The disadvances is that it is more difficult to setup +full text search. The disadvantages are that it is more difficult to setup and does not have live searching capabilities. ' defval='0' depends='SEARCHENGINE'/> </group> @@ -1030,9 +1030,9 @@ If the COMPACT_LATEX tag is set to YES Doxygen generates more compact LaTeX documents. This may be useful for small projects and may help to save some trees in general. ' defval='0' depends='GENERATE_LATEX'/> - <option type='enum' id='PAPER_TYPE' defval='a4wide' docs=' + <option type='enum' id='PAPER_TYPE' defval='a4' docs=' The PAPER_TYPE tag can be used to set the paper type that is used -by the printer. Possible values are: a4, a4wide, letter, legal and +by the printer. Possible values are: a4, letter, legal and executive. If left blank a4wide will be used. ' depends='GENERATE_LATEX'> <value name='a4'/> @@ -1301,9 +1301,8 @@ interpreter (i.e. the result of `which perl'). If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or super classes. Setting the tag to NO turns the diagrams off. Note that -this option is superseded by the HAVE_DOT option below. This is only a -fallback. It is recommended to install and use dot, since it yields more -powerful graphs. +this option also works with HAVE_DOT disabled, but it is recommended to +install and use dot, since it yields more powerful graphs. ' defval='1'/> <option type='string' id='MSCGEN_PATH' format='string' docs=' You can define message sequence charts within doxygen comments using the \msc @@ -1431,6 +1430,12 @@ contain dot files that are included in the documentation (see the \dotfile command). ' depends='HAVE_DOT'> </option> + <option type='list' id='MSCFILE_DIRS' format='dir' docs=' +The MSCFILE_DIRS tag can be used to specify one or more directories that +contain msc files that are included in the documentation (see the +\mscfile command). +' > + </option> <option type='int' id='DOT_GRAPH_MAX_NODES' docs=' The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes that will be shown in the graph. If the number of nodes in a graph diff --git a/src/configoptions.cpp b/src/configoptions.cpp index a9c2133..24c0375 100644 --- a/src/configoptions.cpp +++ b/src/configoptions.cpp @@ -744,7 +744,7 @@ void addConfigOptions(Config *cfg) //---- cb = cfg->addBool( "WARN_NO_PARAMDOC", - "The WARN_NO_PARAMDOC option can be abled to get warnings for\n" + "The WARN_NO_PARAMDOC option can be enabled to get warnings for\n" "functions that are documented, but have no documentation for their parameters\n" "or return value. If set to NO (the default) doxygen will only warn about\n" "wrong or incomplete parameter documentation, but not about the absence of\n" @@ -1541,9 +1541,9 @@ void addConfigOptions(Config *cfg) ce = cfg->addEnum( "PAPER_TYPE", "The PAPER_TYPE tag can be used to set the paper type that is used\n" - "by the printer. Possible values are: a4, a4wide, letter, legal and\n" + "by the printer. Possible values are: a4, letter, legal and\n" "executive. If left blank a4wide will be used.", - "a4wide" + "a4" ); ce->addValue("a4"); ce->addValue("a4wide"); @@ -1978,9 +1978,8 @@ void addConfigOptions(Config *cfg) "If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will\n" "generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base\n" "or super classes. Setting the tag to NO turns the diagrams off. Note that\n" - "this option is superseded by the HAVE_DOT option below. This is only a\n" - "fallback. It is recommended to install and use dot, since it yields more\n" - "powerful graphs.", + "this option also works with HAVE_DOT disabled, but it is recommended to\n" + "install and use dot, since it yields more powerful graphs.", TRUE ); //---- @@ -2186,6 +2185,14 @@ void addConfigOptions(Config *cfg) cl->addDependency("HAVE_DOT"); cl->setWidgetType(ConfigList::Dir); //---- + cl = cfg->addList( + "MSCFILE_DIRS", + "The MSCFILE_DIRS tag can be used to specify one or more directories that\n" + "contain msc files that are included in the documentation (see the\n" + "\\mscfile command)." + ); + cl->setWidgetType(ConfigList::Dir); + //---- ci = cfg->addInt( "DOT_GRAPH_MAX_NODES", "The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of\n" diff --git a/src/definition.cpp b/src/definition.cpp index 6fe8b4e..6cec012 100644 --- a/src/definition.cpp +++ b/src/definition.cpp @@ -252,7 +252,6 @@ void Definition::removeFromMap(Definition *d) DefinitionIntf *di=Doxygen::symbolMap->find(symbolName); if (di) { - ASSERT(di!=0); if (di!=d) // symbolName not unique { //printf(" removing from list: %p!\n",di); @@ -435,6 +434,18 @@ void Definition::setDocumentation(const char *d,const char *docFile,int docLine, #define uni_isupper(c) (QChar(c).category()==QChar::Letter_Uppercase) +// do a UTF-8 aware search for the last real character and return TRUE +// if that is a multibyte one. +static bool lastCharIsMultibyte(const QCString &s) +{ + int l = s.length(); + int p = 0; + int pp = -1; + while ((p=nextUtf8CharPosition(s,l,p))<l) pp=p; + if (pp==-1 || ((uchar)s[pp])<0x80) return FALSE; + return TRUE; +} + void Definition::_setBriefDescription(const char *b,const char *briefFile,int briefLine) { static QCString outputLanguage = Config_getEnum("OUTPUT_LANGUAGE"); @@ -447,11 +458,12 @@ void Definition::_setBriefDescription(const char *b,const char *briefFile,int br int bl = brief.length(); if (bl>0 && needsDot) // add punctuation if needed { - switch(brief.at(bl-1)) + int c = brief.at(bl-1); + switch(c) { - case '.': case '!': case '?': case '>': case ':': break; + case '.': case '!': case '?': case '>': case ':': case ')': break; default: - if (uni_isupper(brief.at(0))) brief+='.'; + if (uni_isupper(brief.at(0)) && !lastCharIsMultibyte(brief)) brief+='.'; break; } } diff --git a/src/diagram.cpp b/src/diagram.cpp index dee8928..bb2d02e 100644 --- a/src/diagram.cpp +++ b/src/diagram.cpp @@ -349,7 +349,7 @@ bool TreeDiagram::layoutTree(DiagramItem *root,int r) DiagramItem *di=dil->first(); while (di && !moved && !di->isInList()) { - moved = moved || layoutTree(di,r+1); + moved = layoutTree(di,r+1); di=dil->next(); } } diff --git a/src/docparser.cpp b/src/docparser.cpp index d68be25..1b95a8c 100644 --- a/src/docparser.cpp +++ b/src/docparser.cpp @@ -70,15 +70,15 @@ static const char *sectionLevelToName[] = // Parser state: global variables during a call to validatingParseDoc static Definition * g_scope; -static QCString g_context; +static QCString g_context; static bool g_inSeeBlock; static bool g_insideHtmlLink; static QStack<DocNode> g_nodeStack; static QStack<DocStyleChange> g_styleStack; static QStack<DocStyleChange> g_initialStyleStack; static QList<Definition> g_copyStack; -static QCString g_fileName; -static QCString g_relPath; +static QCString g_fileName; +static QCString g_relPath; static bool g_hasParamCommand; static bool g_hasReturnCommand; @@ -89,7 +89,7 @@ static QCString g_exampleName; static SectionDict * g_sectionDict; static QCString g_searchUrl; -static QCString g_includeFileText; +static QCString g_includeFileText; static uint g_includeFileOffset; static uint g_includeFileLength; @@ -999,7 +999,6 @@ static void handleUnclosedStyleCommands() } } - static void handleLinkedWord(DocNode *parent,QList<DocNode> &children) { Definition *compound=0; @@ -1113,6 +1112,23 @@ static void handleLinkedWord(DocNode *parent,QList<DocNode> &children) } } +static void handleParameterType(DocNode *parent,QList<DocNode> &children,const QCString ¶mTypes) +{ + QCString name = g_token->name; + int p=0,i; + QCString type; + while ((i=paramTypes.find('|',p))!=-1) + { + g_token->name = paramTypes.mid(p,i-p); + handleLinkedWord(parent,children); + p=i+1; + } + g_token->name = paramTypes.mid(p); + handleLinkedWord(parent,children); + g_token->name = name; +} + + /* Helper function that deals with the most common tokens allowed in * title like sections. * @param parent Parent node, owner of the children list passed as @@ -1562,6 +1578,21 @@ static int internalValidatingParseDoc(DocNode *parent,QList<DocNode> &children, static void readTextFileByName(const QCString &file,QCString &text) { + QStrList &examplePathList = Config_getList("EXAMPLE_PATH"); + char *s=examplePathList.first(); + while (s) + { + QCString absFileName = QCString(s)+portable_pathSeparator()+file; + QFileInfo fi(absFileName); + if (fi.exists()) + { + text = fileToString(absFileName,Config_getBool("FILTER_SOURCE_FILES")); + return; + } + s=examplePathList.next(); + } + + // as a fallback we also look in the exampleNameDict bool ambig; FileDef *fd; if ((fd=findFileDef(Doxygen::exampleNameDict,file,ambig))) @@ -1826,9 +1857,12 @@ void DocCopy::parse() g_scope = def; if (def->definitionType()==Definition::TypeMember && def->getOuterScope()) { - g_context=def->getOuterScope()->name(); + if (def->getOuterScope()!=Doxygen::globalScope) + { + g_context=def->getOuterScope()->name(); + } } - else + else if (def!=Doxygen::globalScope) { g_context=def->name(); } @@ -2526,6 +2560,87 @@ void DocDotFile::parse() ASSERT(n==this); } +DocMscFile::DocMscFile(DocNode *parent,const QCString &name,const QCString &context) : + m_name(name), m_relPath(g_relPath), m_context(context) +{ + m_parent = parent; +} + +void DocMscFile::parse() +{ + g_nodeStack.push(this); + DBG(("DocMscFile::parse() start\n")); + + doctokenizerYYsetStateTitle(); + int tok; + while ((tok=doctokenizerYYlex())) + { + if (!defaultHandleToken(this,tok,m_children)) + { + switch (tok) + { + case TK_COMMAND: + warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Illegal command %s as part of a \\mscfile", + qPrint(g_token->name)); + break; + case TK_SYMBOL: + warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unsupported symbol %s found", + qPrint(g_token->name)); + break; + default: + warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected token %s", + tokToString(tok)); + break; + } + } + } + tok=doctokenizerYYlex(); + while (tok==TK_WORD) // there are values following the title + { + if (g_token->name=="width") + { + m_width=g_token->chars; + } + else if (g_token->name=="height") + { + m_height=g_token->chars; + } + else + { + warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unknown option %s after image title", + qPrint(g_token->name)); + } + tok=doctokenizerYYlex(); + } + ASSERT(tok==0); + doctokenizerYYsetStatePara(); + handlePendingStyleCommands(this,m_children); + + bool ambig; + FileDef *fd = findFileDef(Doxygen::mscFileNameDict,m_name,ambig); + if (fd) + { + m_file = fd->absFilePath(); + } + else if (ambig) + { + warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: included msc file name %s is ambiguous.\n" + "Possible candidates:\n%s",qPrint(m_name), + qPrint(showFileDefMatches(Doxygen::exampleNameDict,m_name)) + ); + } + else + { + warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: included dot file %s is not found " + "in any of the paths specified via MSCFILE_DIRS!",qPrint(m_name)); + } + + DBG(("DocMscFile::parse() end\n")); + DocNode *n=g_nodeStack.pop(); + ASSERT(n==this); +} + + //--------------------------------------------------------------------------- @@ -4052,8 +4167,20 @@ int DocParamList::parse(const QCString &cmdName) { if (m_type==DocParamSect::Param) { - g_hasParamCommand=TRUE; - checkArgumentName(g_token->name,TRUE); + int typeSeparator = g_token->name.find('#'); // explicit type position + if (typeSeparator!=-1) + { + handleParameterType(this,m_paramTypes,g_token->name.left(typeSeparator)); + g_token->name = g_token->name.mid(typeSeparator+1); + g_hasParamCommand=TRUE; + checkArgumentName(g_token->name,TRUE); + ((DocParamSect*)parent())->m_hasTypeSpecifier=TRUE; + } + else + { + g_hasParamCommand=TRUE; + checkArgumentName(g_token->name,TRUE); + } } else if (m_type==DocParamSect::RetVal) { @@ -4163,6 +4290,11 @@ int DocParamSect::parse(const QCString &cmdName,bool xmlContext, Direction d) DBG(("DocParamSect::parse() start\n")); g_nodeStack.push(this); + if (d!=Unspecified) + { + m_hasInOutSpecifier=TRUE; + } + DocParamList *pl = new DocParamList(this,m_type,d); if (m_children.isEmpty()) { @@ -4392,6 +4524,30 @@ void DocPara::handleDotFile(const QCString &cmdName) df->parse(); } +void DocPara::handleMscFile(const QCString &cmdName) +{ + int tok=doctokenizerYYlex(); + if (tok!=TK_WHITESPACE) + { + warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected whitespace after %s command", + qPrint(cmdName)); + return; + } + doctokenizerYYsetStateFile(); + tok=doctokenizerYYlex(); + doctokenizerYYsetStatePara(); + if (tok!=TK_WORD) + { + warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected token %s as the argument of %s", + tokToString(tok),qPrint(cmdName)); + return; + } + QCString name = g_token->name; + DocMscFile *df = new DocMscFile(this,name,g_context); + m_children.append(df); + df->parse(); +} + void DocPara::handleLink(const QCString &cmdName,bool isJavaLink) { int tok=doctokenizerYYlex(); @@ -4549,7 +4705,10 @@ void DocPara::handleInheritDoc() //printf("{InheritDocs:%s=>%s}\n",g_memberDef->qualifiedName().data(),reMd->qualifiedName().data()); docParserPushContext(); g_scope=reMd->getOuterScope(); - g_context=g_scope->name(); + if (g_scope!=Doxygen::globalScope) + { + g_context=g_scope->name(); + } g_memberDef=reMd; g_styleStack.clear(); g_nodeStack.clear(); @@ -4903,6 +5062,9 @@ int DocPara::handleCommand(const QCString &cmdName) case CMD_DOTFILE: handleDotFile(cmdName); break; + case CMD_MSCFILE: + handleMscFile(cmdName); + break; case CMD_LINK: handleLink(cmdName,FALSE); break; @@ -5131,7 +5293,7 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta { // copy attributes HtmlAttribList attrList = tagHtmlAttribs; - // and remove the href attribute + // and remove the src attribute bool result = attrList.remove(index); ASSERT(result); DocImage *img = new DocImage(this,attrList,opt->value,DocImage::Html); @@ -6159,10 +6321,10 @@ DocNode *validatingParseDoc(const char *fileName,int startLine, bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN"); docParserPushContext(); - if (ctx && + if (ctx && ctx!=Doxygen::globalScope && (ctx->definitionType()==Definition::TypeClass || ctx->definitionType()==Definition::TypeNamespace - ) + ) ) { g_context = ctx->name(); @@ -6170,19 +6332,18 @@ DocNode *validatingParseDoc(const char *fileName,int startLine, else if (ctx && ctx->definitionType()==Definition::TypePage) { Definition *scope = ((PageDef*)ctx)->getPageScope(); - if (scope) g_context = scope->name(); + if (scope && scope!=Doxygen::globalScope) g_context = scope->name(); } else if (ctx && ctx->definitionType()==Definition::TypeGroup) { Definition *scope = ((GroupDef*)ctx)->getGroupScope(); - if (scope) g_context = scope->name(); + if (scope && scope!=Doxygen::globalScope) g_context = scope->name(); } else { g_context = ""; } g_scope = ctx; - //printf("g_context=%s\n",g_context.data()); if (indexWords && md && Doxygen::searchIndex) { diff --git a/src/docparser.h b/src/docparser.h index 7a63cb2..6b2a863 100644 --- a/src/docparser.h +++ b/src/docparser.h @@ -131,7 +131,8 @@ class DocNode Kind_ParamList = 44, Kind_InternalRef = 45, Kind_Copy = 46, - Kind_Text = 47 + Kind_Text = 47, + Kind_MscFile = 48 }; /*! Creates a new node */ DocNode() : m_parent(0), m_insidePre(FALSE) {} @@ -350,12 +351,12 @@ class DocVerbatim : public DocNode DocVerbatim(DocNode *parent,const QCString &context, const QCString &text, Type t,bool isExample, const QCString &exampleFile); - Kind kind() const { return Kind_Verbatim; } - Type type() const { return m_type; } + Kind kind() const { return Kind_Verbatim; } + Type type() const { return m_type; } QCString text() const { return m_text; } QCString context() const { return m_context; } - void accept(DocVisitor *v) { v->visit(this); } - bool isExample() const { return m_isExample; } + void accept(DocVisitor *v) { v->visit(this); } + bool isExample() const { return m_isExample; } QCString exampleFile() const { return m_exampleFile; } QCString relPath() const { return m_relPath; } @@ -608,6 +609,31 @@ class DocDotFile : public CompAccept<DocDotFile>, public DocNode QCString m_context; }; +/*! @brief Node representing a msc file */ +class DocMscFile : public CompAccept<DocMscFile>, public DocNode +{ + public: + DocMscFile(DocNode *parent,const QCString &name,const QCString &context); + void parse(); + Kind kind() const { return Kind_MscFile; } + QCString name() const { return m_name; } + QCString file() const { return m_file; } + QCString relPath() const { return m_relPath; } + bool hasCaption() const { return !m_children.isEmpty(); } + QCString width() const { return m_width; } + QCString height() const { return m_height; } + QCString context() const { return m_context; } + void accept(DocVisitor *v) { CompAccept<DocMscFile>::accept(this,v); } + private: + QCString m_name; + QCString m_file; + QCString m_relPath; + QCString m_width; + QCString m_height; + QCString m_context; +}; + + /*! @brief Node representing a link to some item */ class DocLink : public CompAccept<DocLink>, public DocNode { @@ -895,6 +921,7 @@ class DocSimpleSectSep : public DocNode /*! Node representing a parameter section */ class DocParamSect : public CompAccept<DocParamSect>, public DocNode { + friend class DocParamList; public: enum Type { @@ -905,15 +932,21 @@ class DocParamSect : public CompAccept<DocParamSect>, public DocNode In=1, Out=2, InOut=3, Unspecified=0 }; DocParamSect(DocNode *parent,Type t) - : m_type(t) { m_parent = parent; } + : m_type(t), m_dir(Unspecified), + m_hasInOutSpecifier(FALSE), m_hasTypeSpecifier(FALSE) + { m_parent = parent; } int parse(const QCString &cmdName,bool xmlContext,Direction d); Kind kind() const { return Kind_ParamSect; } Type type() const { return m_type; } void accept(DocVisitor *v) { CompAccept<DocParamSect>::accept(this,v); } + bool hasInOutSpecifier() const { return m_hasInOutSpecifier; } + bool hasTypeSpecifier() const { return m_hasTypeSpecifier; } private: Type m_type; Direction m_dir; + bool m_hasInOutSpecifier; + bool m_hasTypeSpecifier; }; /*! Node representing a paragraph in the documentation tree */ @@ -944,6 +977,7 @@ class DocPara : public CompAccept<DocPara>, public DocNode void handleIncludeOperator(const QCString &cmdName,DocIncOperator::Type t); void handleImage(const QCString &cmdName); void handleDotFile(const QCString &cmdName); + void handleMscFile(const QCString &cmdName); void handleInclude(const QCString &cmdName,DocInclude::Type t); void handleLink(const QCString &cmdName,bool isJavaLink); void handleRef(const QCString &cmdName); @@ -965,10 +999,15 @@ class DocParamList : public DocNode public: DocParamList(DocNode *parent,DocParamSect::Type t,DocParamSect::Direction d) : m_type(t), m_dir(d), m_isFirst(TRUE), m_isLast(TRUE) - { m_paragraphs.setAutoDelete(TRUE); m_parent = parent; } + { m_paragraphs.setAutoDelete(TRUE); + m_params.setAutoDelete(TRUE); + m_paramTypes.setAutoDelete(TRUE); + m_parent = parent; + } virtual ~DocParamList() { } Kind kind() const { return Kind_ParamList; } const QList<DocNode> ¶meters() { return m_params; } + const QList<DocNode> ¶mTypes() { return m_paramTypes; } DocParamSect::Type type() const { return m_type; } DocParamSect::Direction direction() const { return m_dir; } void markFirst(bool b=TRUE) { m_isFirst=b; } @@ -989,6 +1028,7 @@ class DocParamList : public DocNode private: QList<DocPara> m_paragraphs; QList<DocNode> m_params; + QList<DocNode> m_paramTypes; DocParamSect::Type m_type; DocParamSect::Direction m_dir; bool m_isFirst; diff --git a/src/docsets.cpp b/src/docsets.cpp index 5138057..fa14cfa 100644 --- a/src/docsets.cpp +++ b/src/docsets.cpp @@ -232,7 +232,7 @@ void DocSets::addContentsItem(bool isDir, void DocSets::addIndexItem(Definition *context,MemberDef *md,const char *) { - if (md==0 || context==0) return; // TODO: also index non members... + if (md==0 && context==0) return; FileDef *fd = 0; ClassDef *cd = 0; diff --git a/src/doctokenizer.l b/src/doctokenizer.l index fa4f28a..0f7dcc1 100644 --- a/src/doctokenizer.l +++ b/src/doctokenizer.l @@ -789,6 +789,15 @@ REFWORD {LABELID}|{REFWORD2} g_token->name = g_token->name.left(yyleng-2); return TK_WORD; } +<St_Param>({LABELID}"|")*{LABELID}{WS}+("&")?"$"{LABELID} { + QCString params = yytext; + int j = params.find('&'); + int i = params.find('$'); + if (j<i && j!=-1) i=j; + QCString types = params.left(i).stripWhiteSpace(); + g_token->name = types+"#"+params.mid(i); + return TK_WORD; + } <St_Param>[^ \t\n,]+ { g_token->name = yytext; return TK_WORD; diff --git a/src/docvisitor.h b/src/docvisitor.h index bd8e540..3a67d20 100644 --- a/src/docvisitor.h +++ b/src/docvisitor.h @@ -65,6 +65,7 @@ class DocIncOperator; class DocHtmlHeader; class DocImage; class DocDotFile; +class DocMscFile; class DocLink; class DocRef; class DocFormula; @@ -158,6 +159,8 @@ class DocVisitor virtual void visitPost(DocImage *) = 0; virtual void visitPre(DocDotFile *) = 0; virtual void visitPost(DocDotFile *) = 0; + virtual void visitPre(DocMscFile *) = 0; + virtual void visitPost(DocMscFile *) = 0; virtual void visitPre(DocLink *) = 0; virtual void visitPost(DocLink *) = 0; virtual void visitPre(DocRef *) = 0; diff --git a/src/doxygen.cpp b/src/doxygen.cpp index eda6119..4d78e16 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -40,6 +40,7 @@ #include "pre.h" #include "tagreader.h" #include "dot.h" +#include "msc.h" #include "docparser.h" #include "dirdef.h" #include "outputlist.h" @@ -112,6 +113,7 @@ FileNameDict *Doxygen::includeNameDict = 0; // include names FileNameDict *Doxygen::exampleNameDict = 0; // examples FileNameDict *Doxygen::imageNameDict = 0; // images FileNameDict *Doxygen::dotFileNameDict = 0; // dot files +FileNameDict *Doxygen::mscFileNameDict = 0; // dot files StringDict Doxygen::namespaceAliasDict(257); // all namespace aliases StringDict Doxygen::tagDestinationDict(257); // all tag locations QDict<void> Doxygen::expandAsDefinedDict(257); // all macros that should be expanded @@ -174,6 +176,7 @@ void clearAll() Doxygen::exampleNameDict->clear(); Doxygen::imageNameDict->clear(); Doxygen::dotFileNameDict->clear(); + Doxygen::mscFileNameDict->clear(); Doxygen::formulaDict.clear(); Doxygen::formulaNameDict.clear(); Doxygen::tagDestinationDict.clear(); @@ -192,6 +195,8 @@ void statistics() Doxygen::imageNameDict->statistics(); fprintf(stderr,"--- dotFileNameDict stats ----\n"); Doxygen::dotFileNameDict->statistics(); + fprintf(stderr,"--- mscFileNameDict stats ----\n"); + Doxygen::mscFileNameDict->statistics(); //fprintf(stderr,"--- g_excludeNameDict stats ----\n"); //g_excludeNameDict.statistics(); fprintf(stderr,"--- aliasDict stats ----\n"); @@ -4243,6 +4248,17 @@ static bool findClassRelation( found = baseClass!=0 && baseClass!=cd; } + if (!found) + { + // for PHP the "use A\B as C" construct map class C to A::B, so we lookup + // the class name also in the alias mapping. + QCString *aliasName = Doxygen::namespaceAliasDict[baseClassName]; + if (aliasName) // see if it is indeed a class. + { + baseClass=getClass(*aliasName); + found = baseClass!=0 && baseClass!=cd; + } + } bool isATemplateArgument = templateNames!=0 && templateNames->find(biName)!=0; // make templSpec canonical // warning: the following line doesn't work for Mixin classes (see bug 560623) @@ -5881,7 +5897,7 @@ static void findMember(EntryNav *rootNav, { LockingPtr<ArgumentList> rmdAl = rmd->argumentList(); - newMember=newMember && + newMember= !matchArguments2(rmd->getOuterScope(),rmd->getFileDef(),rmdAl.pointer(), cd,fd,root->argList, TRUE); @@ -9141,6 +9157,7 @@ void initDoxygen() Doxygen::exampleNameDict->setAutoDelete(TRUE); Doxygen::imageNameDict = new FileNameDict(257); Doxygen::dotFileNameDict = new FileNameDict(257); + Doxygen::mscFileNameDict = new FileNameDict(257); Doxygen::sectionDict.setAutoDelete(TRUE); Doxygen::memGrpInfoDict.setAutoDelete(TRUE); Doxygen::tagDestinationDict.setAutoDelete(TRUE); @@ -9155,6 +9172,7 @@ void cleanUpDoxygen() delete Doxygen::exampleNameDict; delete Doxygen::imageNameDict; delete Doxygen::dotFileNameDict; + delete Doxygen::mscFileNameDict; delete Doxygen::mainPage; delete Doxygen::pageSDict; delete Doxygen::exampleSDict; @@ -9738,6 +9756,18 @@ void searchInputFiles(StringList &inputFiles) s=dotFileList.next(); } + msg("Searching for msc files...\n"); + QStrList &mscFileList=Config_getList("MSCFILE_DIRS"); + s=mscFileList.first(); + while (s) + { + readFileOrDirectory(s,0,Doxygen::mscFileNameDict,0,0, + 0,0,0, + alwaysRecursive); + s=dotFileList.next(); + } + + msg("Searching for files to exclude\n"); QStrList &excludeList = Config_getList("EXCLUDE"); s=excludeList.first(); diff --git a/src/doxygen.css b/src/doxygen.css index 46216c2..39053f8 100644 --- a/src/doxygen.css +++ b/src/doxygen.css @@ -464,6 +464,28 @@ table.memberdecls { font-style: normal; } +.params, .retval, .exception, .tparams { + border-spacing: 6px 2px; +} + +.params .paramname, .retval .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; +} + + + + /* @end */ /* @group Directory (tree) */ diff --git a/src/doxygen.h b/src/doxygen.h index 0c2e7fc..d4edebc 100644 --- a/src/doxygen.h +++ b/src/doxygen.h @@ -92,6 +92,7 @@ class Doxygen static FileNameList *inputNameList; static FileNameDict *imageNameDict; static FileNameDict *dotFileNameDict; + static FileNameDict *mscFileNameDict; static QStrList tagfileList; static MemberNameSDict *memberNameSDict; static MemberNameSDict *functionNameSDict; diff --git a/src/doxygen_css.h b/src/doxygen_css.h index 42878a6..f32c905 100644 --- a/src/doxygen_css.h +++ b/src/doxygen_css.h @@ -464,6 +464,28 @@ " font-style: normal;\n" "}\n" "\n" +".params, .retval, .exception, .tparams {\n" +" border-spacing: 6px 2px;\n" +"} \n" +"\n" +".params .paramname, .retval .paramname {\n" +" font-weight: bold;\n" +" vertical-align: top;\n" +"}\n" +" \n" +".params .paramtype {\n" +" font-style: italic;\n" +" vertical-align: top;\n" +"} \n" +" \n" +".params .paramdir {\n" +" font-family: \"courier new\",courier,monospace;\n" +" vertical-align: top;\n" +"}\n" +"\n" +"\n" +"\n" +"\n" "/* @end */\n" "\n" "/* @group Directory (tree) */\n" diff --git a/src/entry.cpp b/src/entry.cpp index 745a7f9..c8475a6 100644 --- a/src/entry.cpp +++ b/src/entry.cpp @@ -39,7 +39,7 @@ bool ArgumentList::hasDocumentation() const Argument *a; for (ali.toFirst();!hasDocs && (a=ali.current());++ali) { - hasDocs = hasDocs || a->hasDocumentation(); + hasDocs = a->hasDocumentation(); } return hasDocs; } diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp index a5900cc..7de6e52 100644 --- a/src/htmldocvisitor.cpp +++ b/src/htmldocvisitor.cpp @@ -638,14 +638,12 @@ static int getParagraphContext(DocPara *p,bool &isFirst,bool &isLast) case DocNode::Kind_AutoListItem: isFirst=TRUE; isLast =TRUE; - if (isFirst) t=1; - if (isLast) t=3; + t=1; // not used break; case DocNode::Kind_SimpleListItem: isFirst=TRUE; isLast =TRUE; - if (isFirst) t=1; - if (isLast) t=3; + t=1; // not used break; case DocNode::Kind_HtmlListItem: isFirst=isFirstChildNode((DocHtmlListItem*)p->parent(),p); @@ -1172,7 +1170,8 @@ void HtmlDocVisitor::visitPre(DocImage *img) } m_t << "<div align=\"center\">" << endl; m_t << "<img src=\"" << img->relPath() << img->name() << "\" alt=\"" - << baseName << "\"" << "/>" << endl; + << baseName << "\"" << htmlAttribsToString(img->attribs()) + << "/>" << endl; if (img->hasCaption()) { m_t << "<p><strong>"; @@ -1224,6 +1223,26 @@ void HtmlDocVisitor::visitPost(DocDotFile *df) m_t << "</div>" << endl; } +void HtmlDocVisitor::visitPre(DocMscFile *df) +{ + if (m_hide) return; + writeMscFile(df->file(),df->relPath(),df->context()); + m_t << "<div align=\"center\">" << endl; + if (df->hasCaption()) + { + m_t << "<p><strong>"; + } +} +void HtmlDocVisitor::visitPost(DocMscFile *df) +{ + if (m_hide) return; + if (df->hasCaption()) + { + m_t << "</strong></p>" << endl; + } + m_t << "</div>" << endl; +} + void HtmlDocVisitor::visitPre(DocLink *lnk) { if (m_hide) return; @@ -1312,25 +1331,33 @@ void HtmlDocVisitor::visitPre(DocParamSect *s) if (m_hide) return; forceEndParagraph(s); m_t << "<dl><dt><b>"; + QCString className; switch(s->type()) { case DocParamSect::Param: - m_t << theTranslator->trParameters(); break; + m_t << theTranslator->trParameters(); + className="params"; + break; case DocParamSect::RetVal: - m_t << theTranslator->trReturnValues(); break; + m_t << theTranslator->trReturnValues(); + className="retval"; + break; case DocParamSect::Exception: - m_t << theTranslator->trExceptions(); break; + m_t << theTranslator->trExceptions(); + className="exception"; + break; case DocParamSect::TemplateParam: /* TODO: add this m_t << theTranslator->trTemplateParam(); break; */ m_t << "Template Parameters"; break; + className="tparams"; default: ASSERT(0); } m_t << ":"; m_t << "</b></dt><dd>" << endl; - m_t << " <table border=\"0\" cellspacing=\"2\" cellpadding=\"0\">" << endl; + m_t << " <table class=\"" << className << "\">" << endl; } void HtmlDocVisitor::visitPost(DocParamSect *s) @@ -1345,25 +1372,55 @@ void HtmlDocVisitor::visitPost(DocParamSect *s) void HtmlDocVisitor::visitPre(DocParamList *pl) { if (m_hide) return; - m_t << " <tr><td valign=\"top\">"; - if (pl->direction()!=DocParamSect::Unspecified) + m_t << " <tr>"; + DocParamSect *sect = 0; + if (pl->parent()->kind()==DocNode::Kind_ParamSect) { - m_t << "<tt>["; - if (pl->direction()==DocParamSect::In) - { - m_t << "in"; - } - else if (pl->direction()==DocParamSect::Out) + sect=(DocParamSect*)pl->parent(); + } + if (sect && sect->hasInOutSpecifier()) + { + m_t << "<td class=\"paramdir\">"; + if (pl->direction()!=DocParamSect::Unspecified) { - m_t << "out"; + m_t << "["; + if (pl->direction()==DocParamSect::In) + { + m_t << "in"; + } + else if (pl->direction()==DocParamSect::Out) + { + m_t << "out"; + } + else if (pl->direction()==DocParamSect::InOut) + { + m_t << "in,out"; + } + m_t << "]"; } - else if (pl->direction()==DocParamSect::InOut) + m_t << "</td>"; + } + if (sect && sect->hasTypeSpecifier()) + { + m_t << "<td class=\"paramtype\">"; + QListIterator<DocNode> li(pl->paramTypes()); + DocNode *type; + bool first=TRUE; + for (li.toFirst();(type=li.current());++li) { - m_t << "in,out"; + if (!first) m_t << " | "; else first=FALSE; + if (type->kind()==DocNode::Kind_Word) + { + visit((DocWord*)type); + } + else if (type->kind()==DocNode::Kind_LinkedWord) + { + visit((DocLinkedWord*)type); + } } - m_t << "]</tt> "; + m_t << "</td>"; } - m_t << "</td><td valign=\"top\"><em>"; + m_t << "<td class=\"paramname\">"; //QStrListIterator li(pl->parameters()); //const char *s; QListIterator<DocNode> li(pl->parameters()); @@ -1381,7 +1438,7 @@ void HtmlDocVisitor::visitPre(DocParamList *pl) visit((DocLinkedWord*)param); } } - m_t << "</em> </td><td>"; + m_t << "</td><td>"; } void HtmlDocVisitor::visitPost(DocParamList *) diff --git a/src/htmldocvisitor.h b/src/htmldocvisitor.h index b31247f..c033e8b 100644 --- a/src/htmldocvisitor.h +++ b/src/htmldocvisitor.h @@ -103,6 +103,8 @@ class HtmlDocVisitor : public DocVisitor void visitPost(DocImage *); void visitPre(DocDotFile *); void visitPost(DocDotFile *); + void visitPre(DocMscFile *); + void visitPost(DocMscFile *); void visitPre(DocLink *); void visitPost(DocLink *); void visitPre(DocRef *); diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp index 116b6da..60dc956 100644 --- a/src/latexdocvisitor.cpp +++ b/src/latexdocvisitor.cpp @@ -1006,7 +1006,17 @@ void LatexDocVisitor::visitPost(DocDotFile *df) if (m_hide) return; endDotFile(df->hasCaption()); } +void LatexDocVisitor::visitPre(DocMscFile *df) +{ + if (m_hide) return; + startMscFile(df->file(),df->width(),df->height(),df->hasCaption()); +} +void LatexDocVisitor::visitPost(DocMscFile *df) +{ + if (m_hide) return; + endMscFile(df->hasCaption()); +} void LatexDocVisitor::visitPre(DocLink *lnk) { if (m_hide) return; @@ -1082,10 +1092,15 @@ void LatexDocVisitor::visitPost(DocSecRefList *) void LatexDocVisitor::visitPre(DocParamSect *s) { if (m_hide) return; + bool hasInOutSpecs = s->hasInOutSpecifier(); + bool hasTypeSpecs = s->hasTypeSpecifier(); switch(s->type()) { case DocParamSect::Param: - m_t << "\n\\begin{DoxyParams}{"; + m_t << "\n\\begin{DoxyParams}"; + if (hasInOutSpecs && hasTypeSpecs) m_t << "[2]"; // 2 extra cols + else if (hasInOutSpecs || hasTypeSpecs) m_t << "[1]"; // 1 extra col + m_t << "{"; filter(theTranslator->trParameters()); break; case DocParamSect::RetVal: @@ -1134,23 +1149,60 @@ void LatexDocVisitor::visitPost(DocParamSect *s) void LatexDocVisitor::visitPre(DocParamList *pl) { if (m_hide) return; - m_t << "\\item["; - if (pl->direction()!=DocParamSect::Unspecified) + DocParamSect::Type parentType = DocParamSect::Unknown; + DocParamSect *sect = 0; + if (pl->parent() && pl->parent()->kind()==DocNode::Kind_ParamSect) { - m_t << "\\mbox{\\tt["; - if (pl->direction()==DocParamSect::In) - { - m_t << "in"; - } - else if (pl->direction()==DocParamSect::Out) + parentType = ((DocParamSect*)pl->parent())->type(); + sect=(DocParamSect*)pl->parent(); + } + bool useTable = parentType==DocParamSect::Param || + parentType==DocParamSect::RetVal || + parentType==DocParamSect::Exception || + parentType==DocParamSect::TemplateParam; + if (!useTable) + { + m_t << "\\item["; + } + if (sect && sect->hasInOutSpecifier()) + { + if (pl->direction()!=DocParamSect::Unspecified) { - m_t << "out"; + m_t << "\\mbox{\\tt "; + if (pl->direction()==DocParamSect::In) + { + m_t << "in"; + } + else if (pl->direction()==DocParamSect::Out) + { + m_t << "out"; + } + else if (pl->direction()==DocParamSect::InOut) + { + m_t << "in,out"; + } + m_t << "} "; } - else if (pl->direction()==DocParamSect::InOut) + if (useTable) m_t << " & "; + } + if (sect && sect->hasTypeSpecifier()) + { + QListIterator<DocNode> li(pl->paramTypes()); + DocNode *type; + bool first=TRUE; + for (li.toFirst();(type=li.current());++li) { - m_t << "in,out"; + if (!first) m_t << " | "; else first=FALSE; + if (type->kind()==DocNode::Kind_Word) + { + visit((DocWord*)type); + } + else if (type->kind()==DocNode::Kind_LinkedWord) + { + visit((DocLinkedWord*)type); + } } - m_t << "]} "; + if (useTable) m_t << " & "; } m_t << "{\\em "; //QStrListIterator li(pl->parameters()); @@ -1172,11 +1224,34 @@ void LatexDocVisitor::visitPre(DocParamList *pl) } m_insideItem=FALSE; } - m_t << "}]"; + m_t << "}"; + if (useTable) + { + m_t << " & "; + } + else + { + m_t << "]"; + } } -void LatexDocVisitor::visitPost(DocParamList *) +void LatexDocVisitor::visitPost(DocParamList *pl) { + if (m_hide) return; + DocParamSect::Type parentType = DocParamSect::Unknown; + if (pl->parent() && pl->parent()->kind()==DocNode::Kind_ParamSect) + { + parentType = ((DocParamSect*)pl->parent())->type(); + } + bool useTable = parentType==DocParamSect::Param || + parentType==DocParamSect::RetVal || + parentType==DocParamSect::Exception || + parentType==DocParamSect::TemplateParam; + if (useTable) + { + m_t << "\\\\" << endl + << "\\hline" << endl; + } } void LatexDocVisitor::visitPre(DocXRefItem *x) @@ -1358,6 +1433,70 @@ void LatexDocVisitor::endDotFile(bool hasCaption) } } +void LatexDocVisitor::startMscFile(const QCString &fileName, + const QCString &width, + const QCString &height, + bool hasCaption + ) +{ + QCString baseName=fileName; + int i; + if ((i=baseName.findRev('/'))!=-1) + { + baseName=baseName.right(baseName.length()-i-1); + } + if (baseName.right(4)==".eps" || baseName.right(4)==".pdf") + { + baseName=baseName.left(baseName.length()-4); + } + if (baseName.right(4)==".dot") + { + baseName=baseName.left(baseName.length()-4); + } + QCString outDir = Config_getString("LATEX_OUTPUT"); + QCString name = fileName; + writeMscGraphFromFile(name,outDir,baseName,MSC_EPS); + if (hasCaption) + { + m_t << "\n\\begin{DoxyImage}\n"; + } + else + { + m_t << "\n\\begin{DoxyImageNoCaption}\n" + " \\mbox{"; + } + m_t << "\\includegraphics"; + if (!width.isEmpty()) + { + m_t << "[width=" << width << "]"; + } + else if (!height.isEmpty()) + { + m_t << "[height=" << height << "]"; + } + m_t << "{" << baseName << "}"; + + if (hasCaption) + { + m_t << "\n\\caption{"; + } +} + +void LatexDocVisitor::endMscFile(bool hasCaption) +{ + if (m_hide) return; + m_t << "}\n"; // end caption or mbox + if (hasCaption) + { + m_t << "\\end{DoxyImage}\n"; + } + else + { + m_t << "\\end{DoxyImageNoCaption}\n"; + } +} + + void LatexDocVisitor::writeMscFile(const QCString &baseName) { QCString shortName = baseName; diff --git a/src/latexdocvisitor.h b/src/latexdocvisitor.h index 7b7a4d9..39f110e 100644 --- a/src/latexdocvisitor.h +++ b/src/latexdocvisitor.h @@ -106,6 +106,8 @@ class LatexDocVisitor : public DocVisitor void visitPost(DocImage *); void visitPre(DocDotFile *); void visitPost(DocDotFile *); + void visitPre(DocMscFile *); + void visitPost(DocMscFile *); void visitPre(DocLink *lnk); void visitPost(DocLink *); void visitPre(DocRef *ref); @@ -144,6 +146,10 @@ class LatexDocVisitor : public DocVisitor void startDotFile(const QCString &fileName,const QCString &width, const QCString &height, bool hasCaption); void endDotFile(bool hasCaption); + + void startMscFile(const QCString &fileName,const QCString &width, + const QCString &height, bool hasCaption); + void endMscFile(bool hasCaption); void writeMscFile(const QCString &fileName); void pushEnabled(); diff --git a/src/latexgen.cpp b/src/latexgen.cpp index f75b76a..4c5ae50 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -161,7 +161,12 @@ void LatexGenerator::init() t << endl << "clean:" << endl - << "\trm -f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out refman.pdf" << endl; +#if defined(_MSC_VER) + << "\tdel " +#else + << "\trm -f " +#endif + << "*.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out refman.pdf" << endl; createSubDirs(d); } @@ -190,6 +195,8 @@ static void writeDefaultHeaderPart1(FTextStream &t) "\\usepackage{float}\n" "\\usepackage{listings}\n" "\\usepackage{color}\n" + "\\usepackage{ifthen}\n" + "\\usepackage[table]{xcolor}\n" "\\usepackage{textcomp}\n" "\\usepackage{alltt}\n" //"\\usepackage{ae,aecompl,aeguill}\n" @@ -311,7 +318,10 @@ static void writeDefaultStyleSheetPart1(FTextStream &t) "\\RequirePackage{calc}\n" "\\RequirePackage{color}\n" "\\RequirePackage{fancyhdr}\n" - "\\RequirePackage{verbatim}\n\n"; + "\\RequirePackage{longtable}\n" + "\\RequirePackage{verbatim}\n" + "\\RequirePackage{ifthen}\n" + "\\RequirePackage{xcolor}\n\n"; t << "% Use helvetica font instead of times roman\n" "\\RequirePackage{helvet}\n" @@ -601,10 +611,28 @@ static void writeDefaultStyleSheetPart3(FTextStream &t) " \\end{list}%\n" "}\n\n"; t << "% Used by parameter lists\n" - "\\newenvironment{DoxyParams}[1]{%\n" - " \\begin{DoxyDesc}{#1}%\n" + "\\newenvironment{DoxyParams}[2][]{%\n" + " \\begin{DoxyDesc}{#2}%\n" " \\begin{description}%\n" + " \\item[] \\hspace{\\fill} \\vspace{-25pt}%\n" + " \\definecolor{tableShade}{HTML}{F8F8F8}%\n" + " \\rowcolors{1}{white}{tableShade}%\n" + " \\arrayrulecolor{gray}%\n" + " \\setlength{\\tabcolsep}{0.01\\textwidth}%\n" + " \\ifthenelse{\\equal{#1}{}}\n" // default: name, docs columns + " {\\begin{longtable}{|>{\\raggedleft\\hspace{0pt}}p{0.15\\textwidth}|%\n" + " p{0.87\\textwidth}|}}%\n" + " {\\ifthenelse{\\equal{#1}{1}}%\n" // inout, name, docs columns, or type, name, docs columns + " {\\begin{longtable}{|>{\\centering}p{0.10\\textwidth}|%\n" + " >{\\raggedleft\\hspace{0pt}}p{0.15\\textwidth}|%\n" + " p{0.75\\textwidth}|}}%\n" + " {\\begin{longtable}{|>{\\centering}p{0.10\\textwidth}|%\n" // inout, type, name, docs columns + " >{\\centering\\hspace{0pt}}p{0.15\\textwidth}|%\n" + " >{\\raggedleft\\hspace{0pt}}p{0.15\\textwidth}|%\n" + " p{0.58\\textwidth}|}}%\n" + " }\\hline%\n" "}{%\n" + " \\end{longtable}%\n" " \\end{description}%\n" " \\end{DoxyDesc}%\n" "}\n\n"; @@ -617,7 +645,16 @@ static void writeDefaultStyleSheetPart3(FTextStream &t) "\\newenvironment{DoxyRetVals}[1]{%\n" " \\begin{DoxyDesc}{#1}%\n" " \\begin{description}%\n" + " \\item[] \\hspace{\\fill} \\vspace{-25pt}%\n" + " \\definecolor{tableShade}{HTML}{F8F8F8}%\n" + " \\rowcolors{1}{white}{tableShade}%\n" + " \\arrayrulecolor{gray}%\n" + " \\setlength{\\tabcolsep}{0.01\\textwidth}%\n" + " \\begin{longtable}{|>{\\raggedleft\\hspace{0pt}}p{0.25\\textwidth}|%\n" + " p{0.77\\textwidth}|}%\n" + " \\hline%\n" "}{%\n" + " \\end{longtable}%\n" " \\end{description}%\n" " \\end{DoxyDesc}%\n" "}\n\n"; @@ -625,7 +662,16 @@ static void writeDefaultStyleSheetPart3(FTextStream &t) "\\newenvironment{DoxyExceptions}[1]{%\n" " \\begin{DoxyDesc}{#1}%\n" " \\begin{description}%\n" + " \\item[] \\hspace{\\fill} \\vspace{-25pt}%\n" + " \\definecolor{tableShade}{HTML}{F8F8F8}%\n" + " \\rowcolors{1}{white}{tableShade}%\n" + " \\arrayrulecolor{gray}%\n" + " \\setlength{\\tabcolsep}{0.01\\textwidth}%\n" + " \\begin{longtable}{|>{\\raggedleft\\hspace{0pt}}p{0.25\\textwidth}|%\n" + " p{0.77\\textwidth}|}%\n" + " \\hline%\n" "}{%\n" + " \\end{longtable}%\n" " \\end{description}%\n" " \\end{DoxyDesc}%\n" "}\n\n"; @@ -633,7 +679,16 @@ static void writeDefaultStyleSheetPart3(FTextStream &t) "\\newenvironment{DoxyTemplParams}[1]{%\n" " \\begin{DoxyDesc}{#1}%\n" " \\begin{description}%\n" + " \\item[] \\hspace{\\fill} \\vspace{-25pt}%\n" + " \\definecolor{tableShade}{HTML}{F8F8F8}%\n" + " \\rowcolors{1}{white}{tableShade}%\n" + " \\arrayrulecolor{gray}%\n" + " \\setlength{\\tabcolsep}{0.01\\textwidth}%\n" + " \\begin{longtable}{|>{\\raggedleft\\hspace{0pt}}p{0.25\\textwidth}|%\n" + " p{0.77\\textwidth}|}%\n" + " \\hline%\n" "}{%\n" + " \\end{longtable}%\n" " \\end{description}%\n" " \\end{DoxyDesc}%\n" "}\n\n"; diff --git a/src/mandocvisitor.cpp b/src/mandocvisitor.cpp index 902b37c..d1ec0d3 100644 --- a/src/mandocvisitor.cpp +++ b/src/mandocvisitor.cpp @@ -718,6 +718,14 @@ void ManDocVisitor::visitPre(DocDotFile *) void ManDocVisitor::visitPost(DocDotFile *) { } +void ManDocVisitor::visitPre(DocMscFile *) +{ +} + +void ManDocVisitor::visitPost(DocMscFile *) +{ +} + void ManDocVisitor::visitPre(DocLink *) { diff --git a/src/mandocvisitor.h b/src/mandocvisitor.h index 5b7eebe..0be4dd5 100644 --- a/src/mandocvisitor.h +++ b/src/mandocvisitor.h @@ -104,6 +104,8 @@ class ManDocVisitor : public DocVisitor void visitPost(DocImage *); void visitPre(DocDotFile *); void visitPost(DocDotFile *); + void visitPre(DocMscFile *); + void visitPost(DocMscFile *); void visitPre(DocLink *lnk); void visitPost(DocLink *); void visitPre(DocRef *ref); diff --git a/src/message.cpp b/src/message.cpp index cc9925a..cece558 100644 --- a/src/message.cpp +++ b/src/message.cpp @@ -116,8 +116,9 @@ void msg(const char *fmt, ...) static void do_warn(const char *tag, const char *file, int line, const char *fmt, va_list args) { if (!Config_getBool(tag)) return; // warning type disabled - char text[40960]; - vsprintf(text, fmt, args); + char text[4096]; + vsnprintf(text, 4096, fmt, args); + text[4095]='\0'; QCString fileSubst = file==0 ? "<unknown>" : file; QCString lineSubst; lineSubst.setNum(line); QCString textSubst = text; diff --git a/src/msc.cpp b/src/msc.cpp index 87ec5d3..a60ce90 100644 --- a/src/msc.cpp +++ b/src/msc.cpp @@ -112,11 +112,17 @@ void writeMscGraphFromFile(const char *inFile,const char *outDir, } mscArgs+=" -i \""; mscArgs+=inFile; - mscArgs+=".msc\" -o \""; + + if (QCString(inFile).right(4)!=".msc") // add extension if not given + { + mscArgs+=".msc"; + } + mscArgs+="\" -o \""; + mscArgs+=outFile; mscArgs+=extension+"\""; int exitCode; - //printf("*** running: %s %s\n",mscExe.data(),mscArgs.data()); +// printf("*** running: %s %s outDir:%s %s\n",mscExe.data(),mscArgs.data(),outDir,outFile); portable_sysTimerStart(); if ((exitCode=portable_system(mscExe,mscArgs,FALSE))!=0) { @@ -146,6 +152,8 @@ QCString getMscImageMapFromFile(const QCString& inFile, const QCString& outDir, { QCString outFile = inFile + ".map"; + + //printf("*** running:getMscImageMapFromFile \n"); // chdir to the output dir, so dot can find the font file. QCString oldDir = convertToQCString(QDir::currentDirPath()); // go to the html output directory (i.e. path) @@ -154,7 +162,12 @@ QCString getMscImageMapFromFile(const QCString& inFile, const QCString& outDir, QCString mscExe = Config_getString("MSCGEN_PATH")+"mscgen"+portable_commandExtension(); QCString mscArgs = "-T ismap -i \""; - mscArgs+=inFile + ".msc\" -o \""; + mscArgs+=inFile; + if (QCString(inFile).right(4)!=".msc") // add extension if not given + { + mscArgs+=".msc"; + } + mscArgs+="\" -o \""; mscArgs+=outFile + "\""; int exitCode; diff --git a/src/perlmodgen.cpp b/src/perlmodgen.cpp index 49ae643..2b57f6c 100644 --- a/src/perlmodgen.cpp +++ b/src/perlmodgen.cpp @@ -350,6 +350,8 @@ public: void visitPost(DocImage *); void visitPre(DocDotFile *); void visitPost(DocDotFile *); + void visitPre(DocMscFile *); + void visitPost(DocMscFile *); void visitPre(DocLink *); void visitPost(DocLink *); void visitPre(DocRef *); @@ -1094,6 +1096,20 @@ void PerlModDocVisitor::visitPost(DocDotFile *) m_output.add("</dotfile>"); #endif } +void PerlModDocVisitor::visitPre(DocMscFile *) +{ +#if 0 + m_output.add("<mscfile name=\""); m_output.add(df->file()); m_output.add("\">"); +#endif +} + +void PerlModDocVisitor::visitPost(DocMscFile *) +{ +#if 0 + m_output.add("</dotfile>"); +#endif +} + void PerlModDocVisitor::visitPre(DocLink *lnk) { diff --git a/src/printdocvisitor.h b/src/printdocvisitor.h index 44b63f1..b86236d 100644 --- a/src/printdocvisitor.h +++ b/src/printdocvisitor.h @@ -503,6 +503,16 @@ class PrintDocVisitor : public DocVisitor indent_post(); printf("</dotfile>\n"); } + void visitPre(DocMscFile *df) + { + indent_pre(); + printf("<mscfile src=\"%s\">\n",df->name().data()); + } + void visitPost(DocMscFile *) + { + indent_post(); + printf("</mscfile>\n"); + } void visitPre(DocLink *lnk) { indent_pre(); diff --git a/src/rtfdocvisitor.cpp b/src/rtfdocvisitor.cpp index e420601..4886b8d 100644 --- a/src/rtfdocvisitor.cpp +++ b/src/rtfdocvisitor.cpp @@ -22,6 +22,7 @@ #include "doxygen.h" #include "outputgen.h" #include "dot.h" +#include "msc.h" #include "util.h" #include "rtfstyle.h" #include "message.h" @@ -1080,6 +1081,21 @@ void RTFDocVisitor::visitPost(DocDotFile *) DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocDotFile)}\n"); popEnabled(); } +void RTFDocVisitor::visitPre(DocMscFile *df) +{ + DBG_RTF("{\\comment RTFDocVisitor::visitPre(MscDotFile)}\n"); + writeMscFile(df->file()); + + // hide caption since it is not supported at the moment + pushEnabled(); + m_hide=TRUE; +} + +void RTFDocVisitor::visitPost(DocMscFile *) +{ + DBG_RTF("{\\comment RTFDocVisitor::visitPost(MscDotFile)}\n"); + popEnabled(); +} void RTFDocVisitor::visitPre(DocLink *lnk) { @@ -1191,42 +1207,142 @@ void RTFDocVisitor::visitPre(DocParamSect *s) m_t << ":"; m_t << "\\par"; m_t << "}" << endl; - incIndentLevel(); + bool useTable = s->type()==DocParamSect::Param || + s->type()==DocParamSect::RetVal || + s->type()==DocParamSect::Exception || + s->type()==DocParamSect::TemplateParam; + if (!useTable) + { + incIndentLevel(); + } m_t << rtf_Style_Reset << getStyle("DescContinue"); m_lastIsPara=TRUE; } -void RTFDocVisitor::visitPost(DocParamSect *) +void RTFDocVisitor::visitPost(DocParamSect *s) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocParamSect)}\n"); //m_t << "\\par" << endl; - decIndentLevel(); + bool useTable = s->type()==DocParamSect::Param || + s->type()==DocParamSect::RetVal || + s->type()==DocParamSect::Exception || + s->type()==DocParamSect::TemplateParam; + if (!useTable) + { + decIndentLevel(); + } m_t << "}" << endl; } void RTFDocVisitor::visitPre(DocParamList *pl) { + static int columnPos[4][5] = + { { 2, 25, 100, 100, 100 }, // no inout, no type + { 3, 14, 35, 100, 100 }, // inout, no type + { 3, 25, 50, 100, 100 }, // no inout, type + { 4, 14, 35, 55, 100 }, // no inout, type + }; + int config=0; if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocParamList)}\n"); - // Put in the direction: in/out/in,out if specified. - if (pl->direction()!=DocParamSect::Unspecified) + DocParamSect::Type parentType = DocParamSect::Unknown; + DocParamSect *sect = 0; + if (pl->parent() && pl->parent()->kind()==DocNode::Kind_ParamSect) + { + parentType = ((DocParamSect*)pl->parent())->type(); + sect=(DocParamSect*)pl->parent(); + } + bool useTable = parentType==DocParamSect::Param || + parentType==DocParamSect::RetVal || + parentType==DocParamSect::Exception || + parentType==DocParamSect::TemplateParam; + if (sect && sect->hasInOutSpecifier()) config+=1; + if (sect && sect->hasTypeSpecifier()) config+=2; + if (useTable) { - m_t << "["; - if (pl->direction()==DocParamSect::In) + int i; + m_t << "\\trowd \\trgaph108\\trleft426\\tblind426" + "\\trbrdrt\\brdrs\\brdrw10\\brdrcf15 " + "\\trbrdrl\\brdrs\\brdrw10\\brdrcf15 " + "\\trbrdrb\\brdrs\\brdrw10\\brdrcf15 " + "\\trbrdrr\\brdrs\\brdrw10\\brdrcf15 " + "\\trbrdrh\\brdrs\\brdrw10\\brdrcf15 " + "\\trbrdrv\\brdrs\\brdrw10\\brdrcf15 "<< endl; + for (i=0;i<columnPos[config][0];i++) { - m_t << "in"; + m_t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10\\brdrcf15 " + "\\clbrdrl\\brdrs\\brdrw10\\brdrcf15 " + "\\clbrdrb\\brdrs\\brdrw10\\brdrcf15 " + "\\clbrdrr \\brdrs\\brdrw10\\brdrcf15 " + "\\cltxlrtb " + "\\cellx" << (rtf_pageWidth*columnPos[config][i+1]/100) << endl; } - else if (pl->direction()==DocParamSect::Out) + m_t << "\\pard \\widctlpar\\intbl\\adjustright" << endl; + } + + if (sect && sect->hasInOutSpecifier()) + { + if (useTable) { - m_t << "out"; + m_t << "{"; } - else if (pl->direction()==DocParamSect::InOut) + + // Put in the direction: in/out/in,out if specified. + if (pl->direction()!=DocParamSect::Unspecified) { - m_t << "in,out"; + if (pl->direction()==DocParamSect::In) + { + m_t << "in"; + } + else if (pl->direction()==DocParamSect::Out) + { + m_t << "out"; + } + else if (pl->direction()==DocParamSect::InOut) + { + m_t << "in,out"; + } } - m_t << "] "; + + if (useTable) + { + m_t << "\\cell }"; + } + } + + if (sect && sect->hasTypeSpecifier()) + { + if (useTable) + { + m_t << "{"; + } + QListIterator<DocNode> li(pl->paramTypes()); + DocNode *type; + bool first=TRUE; + for (li.toFirst();(type=li.current());++li) + { + if (!first) m_t << " | "; else first=FALSE; + if (type->kind()==DocNode::Kind_Word) + { + visit((DocWord*)type); + } + else if (type->kind()==DocNode::Kind_LinkedWord) + { + visit((DocLinkedWord*)type); + } + } + if (useTable) + { + m_t << "\\cell }"; + } + } + + + if (useTable) + { + m_t << "{"; } m_t << "{\\i "; @@ -1248,14 +1364,41 @@ void RTFDocVisitor::visitPre(DocParamList *pl) } } m_t << "} "; + + if (useTable) + { + m_t << "\\cell }{"; + } m_lastIsPara=TRUE; } -void RTFDocVisitor::visitPost(DocParamList *) +void RTFDocVisitor::visitPost(DocParamList *pl) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocParamList)}\n"); - m_t << "\\par" << endl; + + DocParamSect::Type parentType = DocParamSect::Unknown; + DocParamSect *sect = 0; + if (pl->parent() && pl->parent()->kind()==DocNode::Kind_ParamSect) + { + parentType = ((DocParamSect*)pl->parent())->type(); + sect=(DocParamSect*)pl->parent(); + } + bool useTable = parentType==DocParamSect::Param || + parentType==DocParamSect::RetVal || + parentType==DocParamSect::Exception || + parentType==DocParamSect::TemplateParam; + if (useTable) + { + m_t << "\\cell }" << endl; + //m_t << "\\pard \\widctlpar\\intbl\\adjustright" << endl; + m_t << "{\\row }" << endl; + } + else + { + m_t << "\\par" << endl; + } + m_lastIsPara=TRUE; } diff --git a/src/rtfdocvisitor.h b/src/rtfdocvisitor.h index db7e28b..ccadaa9 100644 --- a/src/rtfdocvisitor.h +++ b/src/rtfdocvisitor.h @@ -104,7 +104,9 @@ class RTFDocVisitor : public DocVisitor void visitPost(DocImage *); void visitPre(DocDotFile *); void visitPost(DocDotFile *); - void visitPre(DocLink *lnk); + void visitPre(DocMscFile *); + void visitPost(DocMscFile *); + void visitPre(DocLink *); void visitPost(DocLink *); void visitPre(DocRef *ref); void visitPost(DocRef *); diff --git a/src/scanner.l b/src/scanner.l index 3e7c6ca..4846433 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -567,6 +567,7 @@ FILE ({FILESCHAR}*{FILEECHAR}+("."{FILESCHAR}*{FILEECHAR}+)*)|("\""[^\n\"]+ ID "$"?[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]* SCOPEID {ID}({ID}*{BN}*"::"{BN}*)*({ID}?) SCOPENAME "$"?(({ID}?{BN}*"::"{BN}*)*)(((~|!){BN}*)?{ID}) +PHPSCOPENAME ({ID}"\\")+{ID} TSCOPE {ID}("<"[a-z_A-Z0-9 \t\*\&,]*">")? CSSCOPENAME (({ID}?{BN}*"."{BN}*)*)((~{BN}*)?{ID}) PRE [pP][rR][eE] @@ -635,6 +636,8 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) %x Comment %x PackageName %x JavaImport +%x PHPUse +%x PHPUseAs %x CSAccessorDecl %x CSGeneric %x PreLineCtrl @@ -1205,10 +1208,11 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) <ObjCSkipStatement>";" { BEGIN(FindMembers); } -<PackageName>{ID}("."{ID})* { +<PackageName>{ID}(("."|"\\"){ID})* { isTypedef=FALSE; current->name = yytext; current->name = substitute(current->name,".","::"); + current->name = substitute(current->name,"\\","::"); current->section = Entry::NAMESPACE_SEC; current->type = "namespace" ; current->fileName = yyFileName; @@ -1286,7 +1290,14 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) current->startLine = yyLineNr; current->bodyLine = yyLineNr; lineCount(); - BEGIN( CompoundName ); + if (insidePHP) + { + BEGIN( PackageName ); + } + else + { + BEGIN( CompoundName ); + } } <FindMembers>{B}*"module"{BN}+ { lineCount(); @@ -1649,14 +1660,57 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) <NSAliasArg>";" { BEGIN( FindMembers ); } +<PHPUse>({ID}{BN}*"\\"{BN}*)+{ID} { + lineCount(); + aliasName=yytext; + //current->fileName = yyFileName; + //current->section=Entry::USINGDIR_SEC; + //current_root->addSubEntry(current); + //current = new Entry; + //initEntry(); + BEGIN(PHPUseAs); + } +<PHPUseAs>{BN}+"as"{BN}+ { + lineCount(); + } +<PHPUseAs>{ID} { + Doxygen::namespaceAliasDict.insert(yytext, + new QCString(removeRedundantWhiteSpace( + substitute(aliasName,"\\","::")))); + aliasName.resize(0); + } +<PHPUseAs>[,;] { + if (!aliasName.isEmpty()) + { + int i=aliasName.findRev('\\'); + QCString an = removeRedundantWhiteSpace( + substitute(aliasName,"\\","::")); + Doxygen::namespaceAliasDict.insert(aliasName.mid(i+1), + new QCString(an)); + current->name = an; + current->fileName = yyFileName; + current->section=Entry::USINGDECL_SEC; + current_root->addSubEntry(current); + current = new Entry ; + initEntry(); + } + if (*yytext==',') + { + BEGIN(PHPUse); + } + else + { + BEGIN(FindMembers); + } + } <JavaImport>({ID}{BN}*"."{BN}*)+"*" { // package import => add as a using directive lineCount(); QCString scope=yytext; - current->name=removeRedundantWhiteSpace(substitute(scope.left(scope.length()-2),".","::")); + current->name=removeRedundantWhiteSpace(substitute(scope.left(scope.length()-1),".","::")); current->fileName = yyFileName; current->section=Entry::USINGDIR_SEC; current_root->addSubEntry(current); - current = new Entry ; + current = new Entry; initEntry(); BEGIN(Using); } @@ -1892,6 +1946,10 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) else // insideJava or insideD BEGIN(JavaImport); } + else if (insidePHP && strcmp(yytext,"use")==0) + { + BEGIN(PHPUse); + } else if (insideJava && strcmp(yytext,"package")==0) { lineCount(); @@ -4783,7 +4841,23 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) <BasesProt>"private"{BN}+ { lineCount(); baseProt = Private; } <BasesProt>{BN} { lineCount(); } <BasesProt>. { unput(*yytext); BEGIN(Bases); } +<Bases>("\\")?{BN}*({ID}{BN}*"\\"{BN}*)*{ID} { + if (!insidePHP) + { + REJECT; + } + else // PHP base class of the form \Ns\Cl or Ns\Cl + { + lineCount(); + QCString bn=yytext; + bn = substitute(bn,"\\","::"); + baseName += bn; + current->args += ' '; + current->args += yytext; + } + } <Bases>("::")?{BN}*({ID}{BN}*"::"{BN}*)*{ID} { + lineCount(); QCString baseScope = yytext; if (insideCS && baseScope.stripWhiteSpace()=="where") { diff --git a/src/textdocvisitor.h b/src/textdocvisitor.h index 081d57e..4c56935 100644 --- a/src/textdocvisitor.h +++ b/src/textdocvisitor.h @@ -102,6 +102,9 @@ class TextDocVisitor : public DocVisitor void visitPost(DocImage *) {} void visitPre(DocDotFile *) {} void visitPost(DocDotFile *) {} + + void visitPre(DocMscFile *) {} + void visitPost(DocMscFile *) {} void visitPre(DocLink *) {} void visitPost(DocLink *) {} void visitPre(DocRef *) {} diff --git a/src/util.cpp b/src/util.cpp index d31781b..b2d026f 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -6445,7 +6445,7 @@ bool updateLanguageMapping(const QCString &extension,const QCString &language) // found the language SrcLangExt parserId = p->parserId; - QCString extName = extension; + QCString extName = extension.lower(); if (extName.isEmpty()) return FALSE; if (extName.at(0)!='.') extName.prepend("."); if (g_extLookup.find(extension)!=0) // language was already register for this ext @@ -6499,7 +6499,7 @@ SrcLangExt getLanguageFromFileName(const QCString fileName) int i = fileName.findRev('.'); if (i!=-1) // name has an extension { - QCString extStr=fileName.right(fileName.length()-i); + QCString extStr=fileName.right(fileName.length()-i).lower(); if (!extStr.isEmpty()) // non-empty extension { int *pVal=g_extLookup.find(extStr); @@ -380,6 +380,7 @@ void writeSummaryLink(OutputList &ol,const char *label,const char *title, QCString externalLinkTarget(); QCString externalRef(const QCString &relPath,const QCString &ref,bool href); +int nextUtf8CharPosition(const QCString &utf8Str,int len,int startPos); #endif diff --git a/src/vhdldocgen.cpp b/src/vhdldocgen.cpp index d4c6d52..bf9c349 100644 --- a/src/vhdldocgen.cpp +++ b/src/vhdldocgen.cpp @@ -294,7 +294,7 @@ MemberDef* VhdlDocGen::findMember(const QCString& className, const QCString& mem tt=tt.upper(); ecd =getClass(tt); } - else if (!ecd) + if (!ecd) { tt=tt.lower(); ecd =getClass(tt); diff --git a/src/xmldocvisitor.cpp b/src/xmldocvisitor.cpp index 2c09a0a..5dfa052 100644 --- a/src/xmldocvisitor.cpp +++ b/src/xmldocvisitor.cpp @@ -711,6 +711,17 @@ void XmlDocVisitor::visitPost(DocDotFile *) m_t << "</dotfile>" << endl; } +void XmlDocVisitor::visitPre(DocMscFile *df) +{ + if (m_hide) return; + m_t << "<mscfile name=\"" << df->file() << "\">"; +} + +void XmlDocVisitor::visitPost(DocMscFile *) +{ + if (m_hide) return; + m_t << "</dotfile>" << endl; +} void XmlDocVisitor::visitPre(DocLink *lnk) { if (m_hide) return; @@ -810,6 +821,24 @@ void XmlDocVisitor::visitPre(DocParamList *pl) DocNode *param; for (li.toFirst();(param=li.current());++li) { + if (pl->paramTypes().count()>0) + { + QListIterator<DocNode> li(pl->paramTypes()); + DocNode *type; + for (li.toFirst();(type=li.current());++li) + { + m_t << "<parametertype>"; + if (type->kind()==DocNode::Kind_Word) + { + visit((DocWord*)type); + } + else if (type->kind()==DocNode::Kind_LinkedWord) + { + visit((DocLinkedWord*)type); + } + m_t << "</parametertype>" << endl; + } + } m_t << "<parametername"; if (pl->direction()!=DocParamSect::Unspecified) { diff --git a/src/xmldocvisitor.h b/src/xmldocvisitor.h index 89001aa..137af25 100644 --- a/src/xmldocvisitor.h +++ b/src/xmldocvisitor.h @@ -105,6 +105,9 @@ class XmlDocVisitor : public DocVisitor void visitPost(DocImage *); void visitPre(DocDotFile *); void visitPost(DocDotFile *); + + void visitPre(DocMscFile *); + void visitPost(DocMscFile *); void visitPre(DocLink *); void visitPost(DocLink *); void visitPre(DocRef *); |