summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--addon/doxywizard/config_doxyw.l29
-rw-r--r--addon/doxywizard/wizard.cpp5
-rw-r--r--doc/arch.doc4
-rw-r--r--doc/faq.doc6
-rw-r--r--examples/define.h4
-rw-r--r--examples/tclexample.tcl16
-rw-r--r--src/code.l6
-rw-r--r--src/commentcnv.l4
-rw-r--r--src/commentscan.l56
-rw-r--r--src/docparser.cpp32
-rw-r--r--src/doctokenizer.l2
-rw-r--r--src/doxygen.cpp2
-rw-r--r--src/fortrancode.l53
-rw-r--r--src/fortranscanner.l49
-rw-r--r--src/markdown.cpp4
-rw-r--r--src/namespacedef.cpp2
-rw-r--r--src/scanner.l5
-rw-r--r--src/tclscanner.l17
-rw-r--r--src/util.cpp6
-rw-r--r--testing/054/054__parblock_8cpp.xml92
-rw-r--r--testing/054_parblock.cpp32
22 files changed, 321 insertions, 107 deletions
diff --git a/.gitignore b/.gitignore
index 440769b..fa8ffb5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,4 +13,4 @@
/doxygen_docs
/doxygen.tag
-/build
+/build*
diff --git a/addon/doxywizard/config_doxyw.l b/addon/doxywizard/config_doxyw.l
index 7874a19..960b7cb 100644
--- a/addon/doxywizard/config_doxyw.l
+++ b/addon/doxywizard/config_doxyw.l
@@ -540,22 +540,34 @@ void writeStringValue(QTextStream &t,QTextCodec *codec,const QString &s)
{
QChar c;
bool needsEscaping=false;
+ bool needsHashEscaping=false;
// convert the string back to it original encoding
//QByteArray se = codec->fromUnicode(s);
t.setCodec(codec);
const QChar *p=s.data();
if (!s.isEmpty() && !p->isNull())
{
- while (!(c=*p++).isNull() && !needsEscaping)
+ if (*p != QChar::fromLatin1('"'))
{
- needsEscaping = (c==QChar::fromLatin1(' ') ||
- c==QChar::fromLatin1('\n') ||
- c==QChar::fromLatin1('\t') ||
- c==QChar::fromLatin1('"'));
+ while (!(c=*p++).isNull() && !needsEscaping)
+ {
+ needsEscaping = (c==QChar::fromLatin1(' ') ||
+ c==QChar::fromLatin1('\n') ||
+ c==QChar::fromLatin1('\t') ||
+ c==QChar::fromLatin1('"'));
+ }
+ p=s.data();
+ while (!(c=*p++).isNull() && !needsHashEscaping)
+ {
+ needsHashEscaping = (c==QChar::fromLatin1('#'));
+ }
}
- if (needsEscaping)
+ if (needsHashEscaping || needsEscaping)
{
t << "\"";
+ }
+ if (needsEscaping)
+ {
p=s.data();
while (!p->isNull())
{
@@ -564,12 +576,15 @@ void writeStringValue(QTextStream &t,QTextCodec *codec,const QString &s)
if (*p ==QChar::fromLatin1('"')) t << "\\"; // escape quotes
t << *p++;
}
- t << "\"";
}
else
{
t << s;
}
+ if (needsHashEscaping || needsEscaping)
+ {
+ t << "\"";
+ }
}
}
diff --git a/addon/doxywizard/wizard.cpp b/addon/doxywizard/wizard.cpp
index b320aaa..ae8fa61 100644
--- a/addon/doxywizard/wizard.cpp
+++ b/addon/doxywizard/wizard.cpp
@@ -1210,18 +1210,23 @@ void Step4::setCallerGraphEnabled(int state)
void Step4::init()
{
+ int id = 0;
if (getBoolOption(m_modelData,STR_HAVE_DOT))
{
m_diagramModeGroup->button(2)->setChecked(true); // Dot
+ id = 2;
}
else if (getBoolOption(m_modelData,STR_CLASS_DIAGRAMS))
{
m_diagramModeGroup->button(1)->setChecked(true); // Builtin diagrams
+ id = 1;
}
else
{
m_diagramModeGroup->button(0)->setChecked(true); // no diagrams
+ id = 0;
}
+ m_dotGroup->setEnabled(id==2);
m_dotClass->setChecked(getBoolOption(m_modelData,STR_CLASS_GRAPH));
m_dotCollaboration->setChecked(getBoolOption(m_modelData,STR_COLLABORATION_GRAPH));
m_dotInheritance->setChecked(getBoolOption(m_modelData,STR_GRAPHICAL_HIERARCHY));
diff --git a/doc/arch.doc b/doc/arch.doc
index a19f450..03c87b9 100644
--- a/doc/arch.doc
+++ b/doc/arch.doc
@@ -139,8 +139,8 @@ strings and executes the commands it finds in it (this is the second pass
in parsing the documentation). It writes the result directly to the output
generators.
-The parser is written in C++ and can be found in src/docparser.cpp. The
-tokens that are eaten by the parser come from src/doctokenizer.l.
+The parser is written in C++ and can be found in \c src/docparser.cpp. The
+tokens that are eaten by the parser come from \c src/doctokenizer.l.
Code fragments found in the comment blocks are passed on to the source parser.
The main entry point for the documentation parser is \c validatingParseDoc()
diff --git a/doc/faq.doc b/doc/faq.doc
index bbad8c0..50dd7b1 100644
--- a/doc/faq.doc
+++ b/doc/faq.doc
@@ -113,7 +113,7 @@ around the blocks that should be hidden and put:
in the config file then all blocks should be skipped by doxygen as long
as \ref cfg_enable_preprocessing "ENABLE_PREPROCESSING" is set to `YES`.
-\section faq_code_inc How can I change what is after the <code>\#include</code> in the class documentation?
+\section faq_code_inc How can I change what is after the \#include in the class documentation?
In most cases you can use \ref cfg_strip_from_inc_path "STRIP_FROM_INC_PATH"
to strip a user defined part of a path.
@@ -210,7 +210,7 @@ remove the % and keep the word unlinked.
No, not as such; doxygen needs to understand the structure of what it reads.
If you don't mind spending some time on it, there are several options:
- If the grammar of X is close to C or C++, then it is probably not too hard to
- tweak src/scanner.l a bit so the language is supported. This is done
+ tweak \c src/scanner.l a bit so the language is supported. This is done
for all other languages directly supported by doxygen
(i.e. Java, IDL, C#, PHP).
- If the grammar of X is somewhat different than you can write an input
@@ -219,7 +219,7 @@ If you don't mind spending some time on it, there are several options:
Javascript, see http://www.stack.nl/~dimitri/doxygen/download.html#helpers).
- If the grammar is completely different one could write a parser for X and
write a backend that produces a similar syntax tree as is done by
- src/scanner.l (and also by src/tagreader.cpp while reading tag files).
+ \c src/scanner.l (and also by \c src/tagreader.cpp while reading tag files).
\section faq_lex Help! I get the cryptic message "input buffer overflow, can't enlarge buffer because scanner uses REJECT"
diff --git a/examples/define.h b/examples/define.h
index c330447..0cd7ae3 100644
--- a/examples/define.h
+++ b/examples/define.h
@@ -10,7 +10,9 @@
*/
/*!
- Computes the absolute value of its argument \a x.
+ \brief Computes the absolute value of its argument \a x.
+ \param x input value.
+ \returns absolute value of \a x.
*/
#define ABS(x) (((x)>0)?(x):-(x))
#define MAX(x,y) ((x)>(y)?(x):(y))
diff --git a/examples/tclexample.tcl b/examples/tclexample.tcl
index 6edef66..e512aee 100644
--- a/examples/tclexample.tcl
+++ b/examples/tclexample.tcl
@@ -10,7 +10,7 @@ exec tclsh "$0" "$@"
#\code
namespace eval ns {
## Documented proc \c ns_proc .
- # param[in] arg some argument
+ # \param[in] arg some argument
proc ns_proc {arg} {}
## Documented var \c ns_var .
# Some documentation.
@@ -22,13 +22,13 @@ namespace eval ns {
## Destroy object.
destructor {exit}
## Documented itcl method \c itcl_method_x .
- # param[in] arg Argument
+ # \param[in] arg Argument
private method itcl_method_x {arg}
## Documented itcl method \c itcl_method_y .
- # param[in] arg Argument
+ # \param[in] arg Argument
protected method itcl_method_y {arg} {}
## Documented itcl method \c itcl_method_z .
- # param[in] arg Argument
+ # \param[in] arg Argument
public method itcl_method_z {arg} {}
## Documented common itcl var \c itcl_Var .
common itcl_Var
@@ -49,13 +49,13 @@ namespace eval ns {
# Defined inside class
variable oo_var
## \private Documented oo method \c oo_method_x .
- # param[in] arg Argument
+ # \param[in] arg Argument
method oo_method_x {arg} {}
## \protected Documented oo method \c oo_method_y .
- # param[in] arg Argument
+ # \param[in] arg Argument
method oo_method_y {arg} {}
## \public Documented oo method \c oo_method_z .
- # param[in] arg Argument
+ # \param[in] arg Argument
method oo_method_z {arg} {}
}
}
@@ -72,7 +72,7 @@ oo::define ns::oo_class {
}
## Documented global proc \c glob_proc .
-# param[in] arg Argument
+# \param[in] arg Argument
proc glob_proc {arg} {puts $arg}
variable glob_var;#< Documented global var \c glob_var\
diff --git a/src/code.l b/src/code.l
index d7d5d74..342583f 100644
--- a/src/code.l
+++ b/src/code.l
@@ -116,6 +116,7 @@ static int g_memCallContext;
static int g_lastCContext;
static int g_skipInlineInitContext;
+static bool g_insideCpp;
static bool g_insideObjC;
static bool g_insideJava;
static bool g_insideCS;
@@ -2415,6 +2416,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\"
g_prefixed_with_this_keyword = TRUE;
}
<Body>{KEYWORD}/([^a-z_A-Z0-9]) {
+ if (g_insideCpp && (QCString(yytext) =="set" ||QCString(yytext) =="get")) REJECT;
startFontClass("keyword");
codifyLines(yytext);
if (QCString(yytext)=="typedef")
@@ -2425,11 +2427,13 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\"
endFontClass();
}
<Body>{KEYWORD}/{B}* {
+ if (g_insideCpp && (QCString(yytext) =="set" ||QCString(yytext) =="get")) REJECT;
startFontClass("keyword");
codifyLines(yytext);
endFontClass();
}
<Body>{KEYWORD}/{BN}*"(" {
+ if (g_insideCpp && (QCString(yytext) =="set" ||QCString(yytext) =="get")) REJECT;
startFontClass("keyword");
codifyLines(yytext);
endFontClass();
@@ -2984,6 +2988,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\"
<MemberCall2,FuncCall>{KEYWORD}/([^a-z_A-Z0-9]) {
//addParmType();
//g_parmName=yytext;
+ if (g_insideCpp && (QCString(yytext) =="set" ||QCString(yytext) =="get")) REJECT;
startFontClass("keyword");
g_code->codify(yytext);
endFontClass();
@@ -3742,6 +3747,7 @@ void parseCCode(CodeOutputInterface &od,const char *className,const QCString &s,
g_insideJava = lang==SrcLangExt_Java;
g_insideCS = lang==SrcLangExt_CSharp;
g_insidePHP = lang==SrcLangExt_PHP;
+ g_insideCpp = lang==SrcLangExt_Cpp;
if (g_sourceFileDef)
{
setCurrentDoc("l00001");
diff --git a/src/commentcnv.l b/src/commentcnv.l
index 44e2543..aca7300 100644
--- a/src/commentcnv.l
+++ b/src/commentcnv.l
@@ -1093,7 +1093,9 @@ void convertCppComments(BufStr *inBuf,BufStr *outBuf,const char *fileName)
if (Debug::isFlagSet(Debug::CommentCnv))
{
g_outBuf->at(g_outBuf->curPos())='\0';
- msg("-------------\n%s\n-------------\n",g_outBuf->data());
+ Debug::print(Debug::CommentCnv,0,"-----------\nCommentCnv: %s\n"
+ "output=[\n%s]\n-----------\n",fileName,g_outBuf->data()
+ );
}
printlex(yy_flex_debug, FALSE, __FILE__, fileName);
}
diff --git a/src/commentscan.l b/src/commentscan.l
index 588d40a..07eb28f 100644
--- a/src/commentscan.l
+++ b/src/commentscan.l
@@ -563,14 +563,7 @@ static void addXRefItem(const char *listName,const char *itemTitle,
RefItem *item = refList->getRefItem(lii->itemId);
ASSERT(item!=0);
item->text += " <p>";
- if (Doxygen::markdownSupport)
- {
- item->text += processMarkdown(yyFileName,yyLineNr,current,outputXRef);
- }
- else
- {
- item->text += outputXRef;
- }
+ item->text += outputXRef;
//printf("%s: text +=%s\n",listName,item->text.data());
}
else // new item
@@ -585,14 +578,7 @@ static void addXRefItem(const char *listName,const char *itemTitle,
sprintf(anchorLabel,"_%s%06d",listName,itemId);
RefItem *item = refList->getRefItem(itemId);
ASSERT(item!=0);
- if (Doxygen::markdownSupport)
- {
- item->text = processMarkdown(yyFileName,yyLineNr,current,outputXRef);
- }
- else
- {
- item->text = outputXRef;
- }
+ item->text = outputXRef;
item->listAnchor = anchorLabel;
docEntry->addSpecialListItem(listName,itemId);
QCString cmdString;
@@ -1860,10 +1846,10 @@ RCSTAG "$"{ID}":"[^\n$]+"$"
addOutput(*yytext);
}
<FormatBlock><<EOF>> {
- QCString endTag = "@end"+blockName;
+ QCString endTag = "end"+blockName;
if (blockName=="startuml") endTag="enduml";
warn(yyFileName,yyLineNr,
- "reached end of comment while inside a @%s block; check for missing @%s tag!",
+ "reached end of comment while inside a \\%s block; check for missing \\%s tag!",
blockName.data(),endTag.data()
);
yyterminate();
@@ -1944,7 +1930,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$"
if (guards.isEmpty())
{
warn(yyFileName,yyLineNr,
- "found @endif without matching start command");
+ "found \\endif without matching start command");
}
else
{
@@ -1962,7 +1948,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$"
if (guards.isEmpty())
{
warn(yyFileName,yyLineNr,
- "found @else without matching start command");
+ "found \\else without matching start command");
}
else
{
@@ -1979,7 +1965,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$"
if (guards.isEmpty())
{
warn(yyFileName,yyLineNr,
- "found @elseif without matching start command");
+ "found \\elseif without matching start command");
}
else
{
@@ -2943,7 +2929,19 @@ bool parseCommentBlock(/* in */ ParserInterface *parser,
langParser = parser;
current = curEntry;
if (comment.isEmpty()) return FALSE; // avoid empty strings
- inputString = comment;
+ if (Doxygen::markdownSupport)
+ {
+ inputString = processMarkdown(fileName,lineNr,NULL,comment);
+ QString qq(inputString);
+ while (qq.startsWith(" ")) qq = qq.mid(1);
+ while (qq.startsWith("\n")) qq = qq.mid(1);
+ if (qq.startsWith("<br>")) qq = qq.mid(4);
+ inputString = QCString(qq.data());
+ }
+ else
+ {
+ inputString = comment;
+ }
inputString.append(" ");
inputPosition = position;
yyLineNr = lineNr;
@@ -2970,7 +2968,7 @@ bool parseCommentBlock(/* in */ ParserInterface *parser,
}
Debug::print(Debug::CommentScan,0,"-----------\nCommentScanner: %s:%d\n"
- "input=[\n%s]\n",qPrint(fileName),lineNr,qPrint(comment)
+ "input=[\n%s]\n",qPrint(fileName),lineNr,qPrint(inputString)
);
commentscanYYrestart( commentscanYYin );
@@ -3008,15 +3006,9 @@ bool parseCommentBlock(/* in */ ParserInterface *parser,
openGroup(current,yyFileName,yyLineNr);
}
- if (Doxygen::markdownSupport)
- {
- current->brief = processMarkdown(fileName,lineNr,current,current->brief);
- current->doc = processMarkdown(fileName,lineNr,current,current->doc);
- current->inbodyDocs = processMarkdown(fileName,lineNr,current,current->inbodyDocs);
- }
-
- Debug::print(Debug::CommentScan,0,
- "brief=[line=%d\n%s]\ndocs=[line=%d\n%s]\ninbody=[line=%d\n%s]\n===========\n",
+ Debug::print(Debug::CommentScan,0,"-----------\nCommentScanner: %s:%d\noutput=[\n"
+ "brief=[line=%d\n%s]\ndocs=[line=%d\n%s]\ninbody=[line=%d\n%s]\n]\n===========\n",
+ qPrint(fileName),lineNr,
current->briefLine,qPrint(current->brief),
current->docLine,qPrint(current->doc),
current->inbodyLine,qPrint(current->inbodyDocs)
diff --git a/src/docparser.cpp b/src/docparser.cpp
index 3d57c2e..0257a1e 100644
--- a/src/docparser.cpp
+++ b/src/docparser.cpp
@@ -451,11 +451,12 @@ static void checkArgumentName(const QCString &name,bool isParam)
}
/*! Checks if the parameters that have been specified using \@param are
- * indeed all parameters.
+ * indeed all parameters and that a parameter does not have multiple
+ * \@param blocks.
* Must be called after checkArgumentName() has been called for each
* argument.
*/
-static void checkUndocumentedParams()
+static void checkUnOrMultipleDocumentedParams()
{
if (g_memberDef && g_hasParamCommand && Config_getBool(WARN_IF_DOC_ERROR))
{
@@ -470,18 +471,37 @@ static void checkUndocumentedParams()
bool found=FALSE;
for (ali.toFirst();(a=ali.current());++ali)
{
+ int count = 0;
QCString argName = g_memberDef->isDefine() ? a->type : a->name;
if (lang==SrcLangExt_Fortran) argName = argName.lower();
argName=argName.stripWhiteSpace();
+ QCString aName = argName;
if (argName.right(3)=="...") argName=argName.left(argName.length()-3);
- if (g_memberDef->getLanguage()==SrcLangExt_Python && (argName=="self" || argName=="cls"))
+ if (lang==SrcLangExt_Python && (argName=="self" || argName=="cls"))
{
// allow undocumented self / cls parameter for Python
}
else if (!argName.isEmpty() && g_paramsFound.find(argName)==0 && a->docs.isEmpty())
{
found = TRUE;
- break;
+ }
+ else
+ {
+ QDictIterator<void> it1(g_paramsFound);
+ void *item1;
+ for (;(item1=it1.current());++it1)
+ {
+ if (argName == it1.currentKey()) count++;
+ }
+ }
+ if (count > 1)
+ {
+ warn_doc_error(g_memberDef->getDefFileName(),
+ g_memberDef->getDefLine(),
+ "argument '" + aName +
+ "' from the argument list of " +
+ QCString(g_memberDef->qualifiedName()) +
+ " has muliple @param documentation sections");
}
}
if (found)
@@ -497,7 +517,7 @@ static void checkUndocumentedParams()
QCString argName = g_memberDef->isDefine() ? a->type : a->name;
if (lang==SrcLangExt_Fortran) argName = argName.lower();
argName=argName.stripWhiteSpace();
- if (g_memberDef->getLanguage()==SrcLangExt_Python && (argName=="self" || argName=="cls"))
+ if (lang==SrcLangExt_Python && (argName=="self" || argName=="cls"))
{
// allow undocumented self / cls parameter for Python
}
@@ -7541,7 +7561,7 @@ DocRoot *validatingParseDoc(const char *fileName,int startLine,
delete v;
}
- checkUndocumentedParams();
+ checkUnOrMultipleDocumentedParams();
detectNoDocumentedParams();
// TODO: These should be called at the end of the program.
diff --git a/src/doctokenizer.l b/src/doctokenizer.l
index 90a8c55..777e963 100644
--- a/src/doctokenizer.l
+++ b/src/doctokenizer.l
@@ -554,7 +554,7 @@ REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
g_token->indent = computeIndent(text,dotPos);
return TK_ENDLIST;
}
-<St_Para>"{"{BLANK}*"@link" {
+<St_Para>"{"{BLANK}*"@link"/{BLANK}+ {
g_token->name = "javalink";
return TK_COMMAND;
}
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index 00826d6..263b59f 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -10965,7 +10965,7 @@ void parseInput()
/**************************************************************************
- * Check/create output directorties *
+ * Check/create output directories *
**************************************************************************/
QCString htmlOutput;
diff --git a/src/fortrancode.l b/src/fortrancode.l
index 501b492..f491acb 100644
--- a/src/fortrancode.l
+++ b/src/fortrancode.l
@@ -159,6 +159,9 @@ static char stringStartSymbol; // single or double quote
// declared from referenced names
static int bracketCount = 0;
+// signal when in type / class /procedure declaration
+static int inTypeDecl = 0;
+
static bool g_endComment;
static void endFontClass()
@@ -687,14 +690,14 @@ CHAR (CHARACTER{ARGS}?|CHARACTER{BS}"*"({BS}[0-9]+|{ARGS}))
TYPE_SPEC (({NUM_TYPE}({BS}"*"{BS}[0-9]+)?)|({NUM_TYPE}{KIND})|DOUBLE{BS}COMPLEX|DOUBLE{BS}PRECISION|{CHAR}|TYPE|CLASS|PROCEDURE)
INTENT_SPEC intent{BS}"("{BS}(in|out|in{BS}out){BS}")"
-ATTR_SPEC (IMPLICIT|ALLOCATABLE|DIMENSION{ARGS}|EXTERNAL|{INTENT_SPEC}|INTRINSIC|OPTIONAL|PARAMETER|POINTER|PROTECTED|PRIVATE|PUBLIC|SAVE|TARGET|RECURSIVE|PURE|IMPURE|ELEMENTAL|VALUE|NOPASS|DEFERRED|CONTIGUOUS|VOLATILE)
+ATTR_SPEC (IMPLICIT|ALLOCATABLE|DIMENSION{ARGS}|EXTERNAL|{INTENT_SPEC}|INTRINSIC|OPTIONAL|PARAMETER|POINTER|PROTECTED|PRIVATE|PUBLIC|SAVE|TARGET|(NON_)?RECURSIVE|PURE|IMPURE|ELEMENTAL|VALUE|NOPASS|DEFERRED|CONTIGUOUS|VOLATILE)
ACCESS_SPEC (PROTECTED|PRIVATE|PUBLIC)
/* Assume that attribute statements are almost the same as attributes. */
ATTR_STMT {ATTR_SPEC}|DIMENSION
FLOW (DO|SELECT|CASE|SELECT{BS}(CASE|TYPE)|WHERE|IF|THEN|ELSE|WHILE|FORALL|ELSEWHERE|ELSEIF|RETURN|CONTINUE|EXIT|GO{BS}TO)
COMMANDS (FORMAT|CONTAINS|MODULE{BS_}PROCEDURE|WRITE|READ|ALLOCATE|ALLOCATED|ASSOCIATED|PRESENT|DEALLOCATE|NULLIFY|SIZE|INQUIRE|OPEN|CLOSE|FLUSH|DATA|COMMON)
IGNORE (CALL)
-PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|IMPURE|PURE|ELEMENTAL)?
+PREFIX ((NON_)?RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,4}((NON_)?RECURSIVE|IMPURE|PURE|ELEMENTAL)?
/* | */
@@ -813,7 +816,8 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I
unput(*yytext);
yy_pop_state();YY_FTN_RESET
}
-<Start>"import"{BS_} {
+<*>"import"{BS}/"\n" |
+<*>"import"{BS_} {
startFontClass("keywordtype");
codifyLines(yytext);
endFontClass();
@@ -825,6 +829,11 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I
generateLink(*g_code, yytext);
g_insideBody=FALSE;
}
+<Import>("ONLY"|"NONE"|"ALL") {
+ startFontClass("keywordtype");
+ codifyLines(yytext);
+ endFontClass();
+ }
/*-------- fortran module -----------------------------------------*/
<Start>("block"{BS}"data"|"program"|"module"|"interface")/{BS_}|({COMMA}{ACCESS_SPEC})|\n { //
startScope();
@@ -836,14 +845,14 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I
if (!qstricmp(yytext,"module")) currentModule="module";
}
<Start>("type")/{BS_}|({COMMA}({ACCESS_SPEC}|ABSTRACT|EXTENDS))|\n { //
- startScope();
- startFontClass("keyword");
- codifyLines(yytext);
- endFontClass();
+ startScope();
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
yy_push_state(YY_START);
- BEGIN(ClassName);
- currentClass="class";
- }
+ BEGIN(ClassName);
+ currentClass="class";
+ }
<ClassName>{ID} {
if (currentModule == "module")
{
@@ -876,7 +885,7 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I
codifyLines(yytext);
endFontClass();
}
-<Start>({PREFIX}{BS_})?{SUBPROG}{BS_} { // Fortran subroutine or function found
+<Start>({PREFIX}{BS_})?{SUBPROG}{BS_} { // Fortran subroutine or function found
startFontClass("keyword");
codifyLines(yytext);
endFontClass();
@@ -923,6 +932,9 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I
}
/*-------- variable declaration ----------------------------------*/
<Start>{TYPE_SPEC}/[,:( ] {
+ QCString typ = yytext;
+ typ = typ.lower();
+ if (typ == "type" || typ == "class" || typ == "procedure") inTypeDecl = 1;
yy_push_state(YY_START);
BEGIN(Declaration);
startFontClass("keywordtype");
@@ -946,7 +958,7 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I
g_code->codify(yytext);
endFontClass();
}
- else if (g_currentMemberDef && ((g_currentMemberDef->isFunction() && (g_currentMemberDef->typeString() != QCString("subroutine"))) ||
+ else if (g_currentMemberDef && ((g_currentMemberDef->isFunction() && (g_currentMemberDef->typeString() != QCString("subroutine") || inTypeDecl)) ||
g_currentMemberDef->isVariable()))
{
generateLink(*g_code, yytext);
@@ -956,22 +968,23 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I
g_code->codify(yytext);
addLocalVar(yytext);
}
- }
-<Declaration>{BS}("=>"|"="){BS} { // Procedure binding
- BEGIN(DeclarationBinding);
- g_code->codify(yytext);
- }
-<DeclarationBinding>{ID} { // Type bound procedure link
+ }
+<Declaration>{BS}("=>"|"="){BS} { // Procedure binding
+ BEGIN(DeclarationBinding);
+ g_code->codify(yytext);
+ }
+<DeclarationBinding>{ID} { // Type bound procedure link
generateLink(*g_code, yytext);
yy_pop_state();
- }
-<Declaration>[(] { // start of array specification
+ }
+<Declaration>[(] { // start of array or type / class specification
bracketCount++;
g_code->codify(yytext);
}
<Declaration>[)] { // end array specification
bracketCount--;
+ if (!bracketCount) inTypeDecl = 0;
g_code->codify(yytext);
}
diff --git a/src/fortranscanner.l b/src/fortranscanner.l
index 85b6de9..774251b 100644
--- a/src/fortranscanner.l
+++ b/src/fortranscanner.l
@@ -198,6 +198,8 @@ static SymbolModifiers currentModifiers;
//! Holds program scope->symbol name->symbol modifiers.
static QMap<Entry*,QMap<QCString,SymbolModifiers> > modifiers;
+static Entry *global_scope = NULL;
+
//-----------------------------------------------------------------------------
static int yyread(char *buf,int max_size);
@@ -248,6 +250,7 @@ SUBPROG (subroutine|function)
B [ \t]
BS [ \t]*
BS_ [ \t]+
+BT_ ([ \t]+|[ \t]*"(")
COMMA {BS},{BS}
ARGS_L0 ("("[^)]*")")
ARGS_L1a [^()]*"("[^)]*")"[^)]*
@@ -271,7 +274,7 @@ ATTR_STMT {ATTR_SPEC}|DIMENSION|{ACCESS_SPEC}
EXTERNAL_STMT (EXTERNAL)
CONTAINS CONTAINS
-PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|IMPURE|PURE|ELEMENTAL)?
+PREFIX ((NON_)?RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,4}((NON_)?RECURSIVE|IMPURE|PURE|ELEMENTAL)?
SCOPENAME ({ID}{BS}"::"{BS})*
%option noyywrap
@@ -558,7 +561,18 @@ SCOPENAME ({ID}{BS}"::"{BS})*
if (!endScope(current_root))
yyterminate();
defaultProtection = Public;
- yy_pop_state();
+ if (global_scope)
+ {
+ if (global_scope != (Entry *) -1)
+ yy_push_state(Start);
+ else
+ yy_pop_state(); // cannot pop artrificial entry
+ }
+ else
+ {
+ yy_push_state(Start);
+ global_scope = (Entry *)-1; // signal that the global_scope has already been used.
+ }
}
<Module>{ID} {
addModule(yytext, TRUE);
@@ -602,7 +616,7 @@ abstract {
current->spec |= Entry::AbstractClass;
}
extends{ARGS} {
- QCString basename = extractFromParens(yytext);
+ QCString basename = extractFromParens(yytext).lower();
current->extends->append(new BaseInfo(basename, Public, Normal));
}
public {
@@ -667,7 +681,8 @@ private {
addCurrentEntry(1);
}
{BS}"=>"[^(\n|\!)]* { /* Specific bindings come after the ID. */
- last_entry->args = yytext;
+ QCString args = yytext;
+ last_entry->args = args.lower();
}
"\n" {
currentModifiers = SymbolModifiers();
@@ -773,8 +788,10 @@ private {
}
{ID} {
}
-^{BS}"type"{BS_}"is"/{BS_} { }
+^{BS}"type"{BS_}"is"/{BT_} { }
^{BS}"type"{BS}"=" { }
+^{BS}"class"{BS_}"is"/{BT_} { }
+^{BS}"class"{BS_}"default" { }
}
<AttributeList>{
{COMMA} {}
@@ -1098,7 +1115,6 @@ private {
yy_push_state(YY_START);
BEGIN(StrIgnore);
debugStr="*!";
- //fprintf(stderr,"start comment %d\n",yyLineNr);
}
}
}
@@ -1552,7 +1568,10 @@ const char* prepassFixedForm(const char* contents, int *hasContLine)
}
// fallthrough
default:
- if(column==6 && emptyLabel) { // continuation
+ if ((column < 6) && ((c - '0') >= 0) && ((c - '0') <= 9)) { // remove numbers, i.e. labels from first 5 positions.
+ newContents[j]=' ';
+ }
+ else if(column==6 && emptyLabel) { // continuation
if (!commented) fullCommentLine=FALSE;
if (c != '0') { // 0 not allowed as continuation character, see f95 standard paragraph 3.3.2.3
newContents[j]=' ';
@@ -2017,14 +2036,23 @@ static void startScope(Entry *scope)
*/
static bool endScope(Entry *scope, bool isGlobalRoot)
{
+ if (global_scope == scope)
+ {
+ global_scope = NULL;
+ return TRUE;
+ }
+ if (global_scope == (Entry *) -1)
+ {
+ return TRUE;
+ }
//cout<<"end scope: "<<scope->name<<endl;
if (current_root->parent() || isGlobalRoot)
{
current_root= current_root->parent(); /* end substructure */
}
- else
+ else // if (current_root != scope)
{
- fprintf(stderr,"parse error in end <scopename>");
+ fprintf(stderr,"parse error in end <scopename>\n");
scanner_abort();
return FALSE;
}
@@ -2558,6 +2586,7 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt, Fortra
yyFileName = fileName;
msg("Parsing file %s...\n",yyFileName.data());
+ global_scope = rt;
startScope(rt); // implies current_root = rt
initParser();
groupEnterFile(yyFileName,yyLineNr);
@@ -2579,7 +2608,7 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt, Fortra
fortranscannerYYlex();
groupLeaveFile(yyFileName,yyLineNr);
- endScope(current_root, TRUE); // TRUE - global root
+ if (global_scope && global_scope != (Entry *) -1) endScope(current_root, TRUE); // TRUE - global root
//debugCompounds(rt); //debug
diff --git a/src/markdown.cpp b/src/markdown.cpp
index d3ec3f1..de5805f 100644
--- a/src/markdown.cpp
+++ b/src/markdown.cpp
@@ -483,6 +483,8 @@ static int processNmdash(GrowBuf &out,const char *data,int off,int size)
{
count++;
}
+ if (count==2 && off>=2 && qstrncmp(data-2,"<!",2)==0) return 0; // start HTML comment
+ if (count==2 && (data[2]=='>')) return 0; // end HTML comment
if (count==2 && (off<8 || qstrncmp(data-8,"operator",8)!=0)) // -- => ndash
{
out.addStr("&ndash;");
@@ -2548,7 +2550,7 @@ QCString processMarkdown(const QCString &fileName,const int lineNr,Entry *e,cons
// finally process the inline markup (links, emphasis and code spans)
processInline(out,s,s.length());
out.addChar(0);
- Debug::print(Debug::Markdown,0,"======== Markdown =========\n---- input ------- \n%s\n---- output -----\n%s\n---------\n",qPrint(input),qPrint(out.get()));
+ Debug::print(Debug::Markdown,0,"======== Markdown =========\n---- input ------- \n%s\n---- output -----\n%s\n=========\n",qPrint(input),qPrint(out.get()));
return out.get();
}
diff --git a/src/namespacedef.cpp b/src/namespacedef.cpp
index c674760..d3eb0df 100644
--- a/src/namespacedef.cpp
+++ b/src/namespacedef.cpp
@@ -961,7 +961,7 @@ void NamespaceSDict::writeDeclaration(OutputList &ol,const char *title,
bool found=FALSE;
for (ni.toFirst();(nd=ni.current()) && !found;++ni)
{
- if (nd->isLinkable())
+ if (nd->isLinkable() && nd->hasDocumentation())
{
SrcLangExt lang = nd->getLanguage();
if (SrcLangExt_IDL==lang)
diff --git a/src/scanner.l b/src/scanner.l
index 08a5e52..619eb5d 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -3639,7 +3639,10 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP})
current->fileName = yyFileName;
current->startLine = yyLineNr;
current->startColumn = yyColNr;
- current->type = "@"; // enum marker
+ if (!(current_root->spec&Entry::Enum))
+ {
+ current->type = "@"; // enum marker
+ }
current->args = current->args.simplifyWhiteSpace();
current->name = current->name.stripWhiteSpace();
current->section = Entry::VARIABLE_SEC;
diff --git a/src/tclscanner.l b/src/tclscanner.l
index 791ecc4..56d2e3d 100644
--- a/src/tclscanner.l
+++ b/src/tclscanner.l
@@ -703,6 +703,7 @@ static void tcl_codify(const char *s,const char *str)
}
else
{
+ if (*(p-2)==0x1A) *(p-2) = '\0'; // remove ^Z
tcl.code->codify(sp);
done=TRUE;
}
@@ -3024,11 +3025,6 @@ void TclLanguageScanner::parseCode(CodeOutputInterface & codeOutIntf,
}
tcl_inf("%s (%d,%d) %d %d\n",myStr.ascii(),startLine,endLine,isExampleBlock,inlineFragment);
//tcl_inf("%s\n"input.data());
- if (isExampleBlock)
- {
- tcl_codify(NULL,input);
- return;
- }
tcl_init();
tcl.collectXRefs = collectXRefs;
tcl.memberdef = memberDef;
@@ -3047,8 +3043,15 @@ tcl_inf("%s (%d,%d) %d %d\n",myStr.ascii(),startLine,endLine,isExampleBlock,inli
}
tcl.file_name = "";
tcl.this_parser = NULL;
- tcl.entry_main = tcl_entry_new();
- tcl_parse(myNs,myCls);
+ if (isExampleBlock)
+ {
+ tcl_codify(NULL,input);
+ }
+ else
+ {
+ tcl.entry_main = tcl_entry_new();
+ tcl_parse(myNs,myCls);
+ }
tcl.code->endCodeLine();
tcl.scan.clear();
tcl.ns.clear();
diff --git a/src/util.cpp b/src/util.cpp
index 3af1a90..9100706 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -1856,7 +1856,11 @@ QCString removeRedundantWhiteSpace(const QCString &s)
case '&':
if (i>0 && isId(pc))
{
- *dst++=' ';
+ if (nc != '=')
+ // avoid splitting operator&=
+ {
+ *dst++=' ';
+ }
}
*dst++=c;
break;
diff --git a/testing/054/054__parblock_8cpp.xml b/testing/054/054__parblock_8cpp.xml
index ae6e462..5567908 100644
--- a/testing/054/054__parblock_8cpp.xml
+++ b/testing/054/054__parblock_8cpp.xml
@@ -80,6 +80,96 @@
<parameterdescription>
<para>
<parblock>
+ <para>First paragraph of the param description.</para>
+ <para>Second paragraph of the param description. </para>
+ </parblock>
+ </para>
+ </parameterdescription>
+ </parameteritem>
+ </parameterlist>
+ </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="054_parblock.cpp" line="33" column="1"/>
+ </memberdef>
+ <memberdef kind="function" id="054__parblock_8cpp_1a5cded03ec9e6fd626da35ab05f624f39" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void function_2</definition>
+ <argsstring>(int client, int *resource, int parblock, int *test, int p)</argsstring>
+ <name>function_2</name>
+ <param>
+ <type>int</type>
+ <declname>client</declname>
+ </param>
+ <param>
+ <type>int *</type>
+ <declname>resource</declname>
+ </param>
+ <param>
+ <type>int</type>
+ <declname>parblock</declname>
+ </param>
+ <param>
+ <type>int *</type>
+ <declname>test</declname>
+ </param>
+ <param>
+ <type>int</type>
+ <declname>p</declname>
+ </param>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>call by target-specific code to manage resources required by the client.</para>
+ <para>
+ <parameterlist kind="param">
+ <parameteritem>
+ <parameternamelist>
+ <parametername direction="in">client</parametername>
+ </parameternamelist>
+ <parameterdescription>
+ <para>ID of client requesting resource. </para>
+ </parameterdescription>
+ </parameteritem>
+ <parameteritem>
+ <parameternamelist>
+ <parametername direction="out">resource</parametername>
+ </parameternamelist>
+ <parameterdescription>
+ <para>Requested resource </para>
+ </parameterdescription>
+ </parameteritem>
+ <parameteritem>
+ <parameternamelist>
+ <parametername direction="in">parblock</parametername>
+ </parameternamelist>
+ <parameterdescription>
+ <para>
+ <parblock>
+ <para>This is a test for the @parblock command.</para>
+ <para>A list if values for the parblock param:<itemizedlist><listitem><para>Item 1. This is short one-line description.</para></listitem><listitem><para>Item 2. This is a long bullet item; sometimes they wrap on multiple lines like this one.</para></listitem></itemizedlist>
+</para>
+ <para>This is the second paragraph description for the @parblock parameter. Always end the text inside the @parblock command with an @endparblock command. </para>
+ </parblock>
+ </para>
+ </parameterdescription>
+ </parameteritem>
+ <parameteritem>
+ <parameternamelist>
+ <parametername direction="out">test</parametername>
+ </parameternamelist>
+ <parameterdescription>
+ <para>This is a test parameter for this function to see if it is included in the parameter table </para>
+ </parameterdescription>
+ </parameteritem>
+ <parameteritem>
+ <parameternamelist>
+ <parametername direction="in">p</parametername>
+ </parameternamelist>
+ <parameterdescription>
+ <para>
+ <parblock>
<para>First paragraph of the param description. <verbatim> Second paragraph of the param description.
</verbatim> </para>
</parblock>
@@ -91,7 +181,7 @@
</detaileddescription>
<inbodydescription>
</inbodydescription>
- <location file="054_parblock.cpp" line="32" column="1"/>
+ <location file="054_parblock.cpp" line="60" column="1"/>
</memberdef>
</sectiondef>
<briefdescription>
diff --git a/testing/054_parblock.cpp b/testing/054_parblock.cpp
index 186feb5..4f303c6 100644
--- a/testing/054_parblock.cpp
+++ b/testing/054_parblock.cpp
@@ -24,9 +24,37 @@
@endparblock
@param[out] test This is a test parameter for this function to see if
it is included in the parameter table
+ @param[in] p
+ @parblock First paragraph of the param description.
+
+ Second paragraph of the param description.
+ @endparblock
+ */
+void function(int client,int *resource,int parblock,int *test,int p);
+/**
+ call by target-specific code to manage resources required by the client.
+
+ @param[in] client ID of client requesting resource.
+ @param[out] resource Requested resource
+ @param[in] parblock @parblock This is a test for the \@parblock
+ command.
+
+ A list if values for the parblock param:
+ - Item 1. This is short one-line description.
+ - Item 2. This is a long bullet item;
+ sometimes they wrap on multiple lines like this
+ one.
+
+ This is the second paragraph description for the
+ \@parblock parameter. Always end the text inside
+ the \@parblock command with an \@endparblock
+ command.
+ @endparblock
+ @param[out] test This is a test parameter for this function to see if
+ it is included in the parameter table
@param[in] p @parblock First paragraph of the param description.
Second paragraph of the param description.
- @endparblock
+ @endparblock
*/
-void function(int client,int *resource,int parblock,int *test,int p);
+void function_2(int client,int *resource,int parblock,int *test,int p);