From 3514452268bf860ac7516185adc0907817ccda97 Mon Sep 17 00:00:00 2001 From: albert-github Date: Mon, 12 Feb 2018 18:24:01 +0100 Subject: Consistency for "group" commands When a non-recognized character appears in a group-command id this is echoed to the console as the default (lex-)rule will be used. This patch ignores these characters, furthermore in case of a \ in the description this is shown in the output as well. --- src/commentscan.l | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/commentscan.l b/src/commentscan.l index 588d40a..a0f0361 100644 --- a/src/commentscan.l +++ b/src/commentscan.l @@ -1517,14 +1517,16 @@ RCSTAG "$"{ID}":"[^\n$]+"$" if (*yytext=='\n') yyLineNr++; BEGIN( Comment ); } +. { // ignore other stuff + } "\\"{B}*"\n" { // line continuation yyLineNr++; addOutput('\n'); } -[^\n\\\*]+ { // title (stored in type) +[^\n\*]+ { // title (stored in type) current->type += yytext; current->type = current->type.stripWhiteSpace(); - } + } {DOCNL} { if ( current->groupDocType==Entry::GROUPDOC_NORMAL && current->type.isEmpty() -- cgit v0.12 From 5f11678370f55e491fa9a04b7fd03cd473f8982f Mon Sep 17 00:00:00 2001 From: albert-github Date: Mon, 12 Feb 2018 19:07:18 +0100 Subject: Fortran improvements - adding NON_RECURSIVE - better handling of missing PROGRAM in case of following module / subroutine in same file - ignore (numeric)-labels in fixed source form - adding support for - TYPE IS - CLASS IS - CLASS DEFAULT --- src/fortrancode.l | 4 ++-- src/fortranscanner.l | 44 ++++++++++++++++++++++++++++++++++++-------- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/fortrancode.l b/src/fortrancode.l index 501b492..7040bbf 100644 --- a/src/fortrancode.l +++ b/src/fortrancode.l @@ -687,14 +687,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)? /* | */ diff --git a/src/fortranscanner.l b/src/fortranscanner.l index 85b6de9..0548cc3 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 > 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. + } } {ID} { addModule(yytext, TRUE); @@ -773,8 +787,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" { } } { {COMMA} {} @@ -1098,7 +1114,6 @@ private { yy_push_state(YY_START); BEGIN(StrIgnore); debugStr="*!"; - //fprintf(stderr,"start comment %d\n",yyLineNr); } } } @@ -1552,7 +1567,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 +2035,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: "<name<parent() || isGlobalRoot) { current_root= current_root->parent(); /* end substructure */ } - else + else // if (current_root != scope) { - fprintf(stderr,"parse error in end "); + fprintf(stderr,"parse error in end \n"); scanner_abort(); return FALSE; } @@ -2558,6 +2585,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 +2607,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 -- cgit v0.12 From e2b0f27d6fca5dacfedc79a1a4eff32d5e9254e9 Mon Sep 17 00:00:00 2001 From: albert-github Date: Wed, 14 Feb 2018 19:10:03 +0100 Subject: Bug 683564 - Value from enumeration followed with semicolon is not present in java docs For java the type should not be reset to "@", see also rule "," --- src/scanner.l | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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; -- cgit v0.12 From bad04c77bd626e5badf7654136b6a5dfa20c6b93 Mon Sep 17 00:00:00 2001 From: albert-github Date: Thu, 15 Feb 2018 15:14:18 +0100 Subject: Ignore build* directories and not just build in case of parallel build directories is is better to ignore the build* directories --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 440769b..fa8ffb5 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,4 @@ /doxygen_docs /doxygen.tag -/build +/build* -- cgit v0.12 From 4013e52ba0f87eb12f8a1c8cb3b2714c0d519a81 Mon Sep 17 00:00:00 2001 From: albert-github Date: Thu, 15 Feb 2018 15:25:15 +0100 Subject: Fortran improvements (2) - handling of type / class statement especially in declarations in source browser and scanner - color code import statement in source browser --- src/fortrancode.l | 49 +++++++++++++++++++++++++++++++------------------ src/fortranscanner.l | 5 +++-- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/src/fortrancode.l b/src/fortrancode.l index 501b492..1ad184f 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() @@ -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 } -"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; } +("ONLY"|"NONE"|"ALL") { + startFontClass("keywordtype"); + codifyLines(yytext); + endFontClass(); + } /*-------- fortran module -----------------------------------------*/ ("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"; } ("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"; + } {ID} { if (currentModule == "module") { @@ -876,7 +885,7 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I codifyLines(yytext); endFontClass(); } -({PREFIX}{BS_})?{SUBPROG}{BS_} { // Fortran subroutine or function found +({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 ----------------------------------*/ {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); } - } -{BS}("=>"|"="){BS} { // Procedure binding - BEGIN(DeclarationBinding); - g_code->codify(yytext); - } -{ID} { // Type bound procedure link + } +{BS}("=>"|"="){BS} { // Procedure binding + BEGIN(DeclarationBinding); + g_code->codify(yytext); + } +{ID} { // Type bound procedure link generateLink(*g_code, yytext); yy_pop_state(); - } -[(] { // start of array specification + } +[(] { // start of array or type / class specification bracketCount++; g_code->codify(yytext); } [)] { // end array specification bracketCount--; + if (!bracketCount) inTypeDecl = 0; g_code->codify(yytext); } diff --git a/src/fortranscanner.l b/src/fortranscanner.l index 85b6de9..ca071cf 100644 --- a/src/fortranscanner.l +++ b/src/fortranscanner.l @@ -602,7 +602,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 +667,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(); -- cgit v0.12 From 1a16a1be6eff7c32795455e47c09b9452f7c3a4e Mon Sep 17 00:00:00 2001 From: albert-github Date: Tue, 20 Feb 2018 13:09:45 +0100 Subject: Consistent warning messages Remove second @ from warning message and replace all @ with \ in warnings for comments in comment scanner. Error showed up in (Lapack v3.8.0): .../lapack/BLAS/SRC/sdsdot.f:25: warning: reached end of comment while inside a @verbatim block; check for missing @@endverbatim tag! --- src/commentscan.l | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/commentscan.l b/src/commentscan.l index 588d40a..727bbb9 100644 --- a/src/commentscan.l +++ b/src/commentscan.l @@ -1860,10 +1860,10 @@ RCSTAG "$"{ID}":"[^\n$]+"$" addOutput(*yytext); } <> { - 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 +1944,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 +1962,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 +1979,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" if (guards.isEmpty()) { warn(yyFileName,yyLineNr, - "found @elseif without matching start command"); + "found \\elseif without matching start command"); } else { -- cgit v0.12 From 05bec28930831888b6dfb610307a04da2d345924 Mon Sep 17 00:00:00 2001 From: albert-github Date: Thu, 22 Feb 2018 19:40:07 +0100 Subject: Bug 793702 - Examples of TCL files fail to display - placed handling of example at the right place - removed ^Z symbol --- src/tclscanner.l | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) 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(); -- cgit v0.12 From f1274b44ad4cb7b4c1a04893b5ad17f830600af4 Mon Sep 17 00:00:00 2001 From: albert-github Date: Fri, 23 Feb 2018 14:50:13 +0100 Subject: Documentation correction - corrected tcl documentation in respect to use of param, has to be \param - added to define documentation possibilities of \param and \return --- examples/define.h | 4 +++- examples/tclexample.tcl | 16 ++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) 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\ -- cgit v0.12 From 17c8c0ee8c0dd06938f3b85db6361de24c1bbe58 Mon Sep 17 00:00:00 2001 From: albert-github Date: Mon, 26 Feb 2018 13:19:36 +0100 Subject: Documentation corrections Corrected the way files are displaced (should be in "code mode") --- doc/arch.doc | 4 ++-- doc/faq.doc | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/arch.doc b/doc/arch.doc index e5fbbdc..337f4dd 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..61d516b 100644 --- a/doc/faq.doc +++ b/doc/faq.doc @@ -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" -- cgit v0.12 From 3c0327c1f8461a029c83b744d076617e28cd26bf Mon Sep 17 00:00:00 2001 From: albert-github Date: Mon, 26 Feb 2018 16:23:26 +0100 Subject: Debug output commentcnv independent of QUIET setting The debug output of the commentcnv (-d commentcnv) should be independent of the setting of QUIET in the doxygen configuration file. --- src/commentcnv.l | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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); } -- cgit v0.12 From a06b1020839f36e3b2ea73c09d9ead7f75983549 Mon Sep 17 00:00:00 2001 From: albert-github Date: Mon, 26 Feb 2018 20:09:45 +0100 Subject: Bug 688387 - JavaDoc @linkplain is not recognized See to it that the, JavaDoc version of the, command @link cannot be confused with @linkplain. --- src/doctokenizer.l | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; } -"{"{BLANK}*"@link" { +"{"{BLANK}*"@link"/{BLANK}+ { g_token->name = "javalink"; return TK_COMMAND; } -- cgit v0.12 From f1148cc406d6e1eefd146f35e766b62bd376cdc3 Mon Sep 17 00:00:00 2001 From: albert-github Date: Mon, 26 Feb 2018 20:13:54 +0100 Subject: Correction in title of FAQ Removed from title of FAQ as this text is shown literal and this is not the intention. --- doc/faq.doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/faq.doc b/doc/faq.doc index bbad8c0..08d0783 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 \#include 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. -- cgit v0.12 From d39cdf826f15470def2ca36bc636868a62c42bbf Mon Sep 17 00:00:00 2001 From: albert-github Date: Tue, 27 Feb 2018 15:48:55 +0100 Subject: Bug 793862 - Missed warning opportunity: duplicated arguments In case an argument has been documented multiple times a warning message is given. --- src/docparser.cpp | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) 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 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. -- cgit v0.12 From 8bf975ea2861def50f9b7d4cca0fb4002c991ec0 Mon Sep 17 00:00:00 2001 From: albert-github Date: Tue, 27 Feb 2018 18:28:40 +0100 Subject: Bug 788873 - Disabled controls when `HAVE_DOT` is already set to `YES` Explicitly call the routine to set the status of the sub list. --- addon/doxywizard/wizard.cpp | 5 +++++ 1 file changed, 5 insertions(+) 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)); -- cgit v0.12 From 0bdaf4541c2495b3166386992666f842c38642c1 Mon Sep 17 00:00:00 2001 From: albert-github Date: Wed, 28 Feb 2018 11:55:04 +0100 Subject: Bug 611240 - C# keywords 'get' and 'set' are highlighted as reserved words in C++ documentation source browser. In case of Cpp don't see 'get' and 'set' as keywords, but in case the keyword rule is used REJECT the rule and give other rules a chance (e.g. the function rule). --- src/code.l | 6 ++++++ 1 file changed, 6 insertions(+) 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; } {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(); } {KEYWORD}/{B}* { + if (g_insideCpp && (QCString(yytext) =="set" ||QCString(yytext) =="get")) REJECT; startFontClass("keyword"); codifyLines(yytext); endFontClass(); } {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}\" {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"); -- cgit v0.12 From e15c80cbf1c0f35c2d2ddc950e3d653bc24aac4e Mon Sep 17 00:00:00 2001 From: albert-github Date: Wed, 28 Feb 2018 14:24:04 +0100 Subject: Bug 653502 - Can't use pound sign in alias command, escaped or unescaped - In case there is already a double quote at the beginning of the line disable further escaping (assume that there is an end double quote as well) - In case a hash sign is present see to it that the string will have double quotes around the alias. --- addon/doxywizard/config_doxyw.l | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) 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 << "\""; + } } } -- cgit v0.12 From 824025bdec187c07b744e4a1fa0837b932d13679 Mon Sep 17 00:00:00 2001 From: albert-github Date: Sun, 4 Mar 2018 12:25:21 +0100 Subject: Documentation update regarding right font usage in architecture chapter Small update, setting program names in right font --- doc/arch.doc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/arch.doc b/doc/arch.doc index e5fbbdc..a19f450 100644 --- a/doc/arch.doc +++ b/doc/arch.doc @@ -190,12 +190,12 @@ could extract information from the XML output. Possible tools could be: Since doxygen uses a lot of \c flex code it is important to understand how \c flex works (for this one should read the \c man page) and to understand what it is doing when \c flex is parsing some input. -Fortunately, when flex is used with the `-d` option it outputs what rules +Fortunately, when \c flex is used with the `-d` option it outputs what rules matched. This makes it quite easy to follow what is going on for a particular input fragment. -To make it easier to toggle debug information for a given flex file I -wrote the following perl script, which automatically adds or removes `-d` +To make it easier to toggle debug information for a given \c flex file I +wrote the following \c perl script, which automatically adds or removes `-d` from the correct line in the \c Makefile: \verbatim @@ -240,7 +240,7 @@ $now = time; utime $now, $now, $file; \endverbatim Another way to get rules matching / debugging information -from the \c flex code is setting LEX_FLAGS with \c make (`make LEX_FLAGS=-d`). +from the \c flex code is setting \c LEX_FLAGS with \c make (`make LEX_FLAGS=-d`). Note that by running doxygen with `-d lex` you get information about which `flex codefile` is used. -- cgit v0.12 From 5bae9d9ec8e5a253d6f5e8f15be43b85cd7ae0ff Mon Sep 17 00:00:00 2001 From: albert-github Date: Sun, 4 Mar 2018 13:04:29 +0100 Subject: Bug 792122 - XHTML pages are broken several ways The Markdown processing was done after the normal tag processing and splitting the comment in brief, doc, inline. This resulted in that sectioning parts (i.e. e.g. ==== conversion to

) remained in the brief description whilst similar constructs with HTML commands landed in the doc (details) description. By performing the markdown on the entire comment block this problem has been overcome. commentscan.l - change moment of calling markdown processing - skip start spaces and subsequent empty lines in markdown processed code - small debug correction markdown.cpp - don't convert the dashes in (HTML type comment) - small debug correction 054 test - update of example for compatibility and adding part about none code result. doxygen.cpp - small textual comment correction --- src/commentscan.l | 46 ++++++++----------- src/doxygen.cpp | 2 +- src/markdown.cpp | 4 +- testing/054/054__parblock_8cpp.xml | 92 +++++++++++++++++++++++++++++++++++++- testing/054_parblock.cpp | 32 ++++++++++++- 5 files changed, 144 insertions(+), 32 deletions(-) diff --git a/src/commentscan.l b/src/commentscan.l index 588d40a..34db454 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 += "

"; - 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; @@ -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("
")) 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/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/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,"')) return 0; // end HTML comment if (count==2 && (off<8 || qstrncmp(data-8,"operator",8)!=0)) // -- => ndash { out.addStr("–"); @@ -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/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 @@ + First paragraph of the param description. + Second paragraph of the param description. + + + + + + + + + + + + + void + void function_2 + (int client, int *resource, int parblock, int *test, int p) + function_2 + + int + client + + + int * + resource + + + int + parblock + + + int * + test + + + int + p + + + + + call by target-specific code to manage resources required by the client. + + + + + client + + + ID of client requesting resource. + + + + + resource + + + Requested resource + + + + + 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. + + + + + + + test + + + This is a test parameter for this function to see if it is included in the parameter table + + + + + p + + + + First paragraph of the param description. Second paragraph of the param description. @@ -91,7 +181,7 @@ - + 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); -- cgit v0.12 From e5e75b7f713251dd6caa472f9c5fb8d49e36ff5a Mon Sep 17 00:00:00 2001 From: albert-github Date: Sun, 4 Mar 2018 18:54:04 +0100 Subject: Bug 778012 - Python List as Default Parameter not parsed correctly Added handling of square brackets, single quoted strings and double quoted strings (could contain comma's as well) to default values of arguments. --- src/pyscanner.l | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/pyscanner.l b/src/pyscanner.l index 9c21d41..1d964b4 100644 --- a/src/pyscanner.l +++ b/src/pyscanner.l @@ -109,7 +109,7 @@ static QCString g_packageName; //static bool g_hideClassDocs; -static QCString g_defVal; +static QGString g_defVal; static int g_braceCount; static bool g_lexInit = FALSE; @@ -993,35 +993,49 @@ STARTDOCSYMS "##" } { - "(" { // internal opening brace + "[" | + "(" { // internal opening brace, assumption is that we have correct code so braces do match g_braceCount++; g_defVal+=*yytext; } "," | + "]" | ")" { if (g_braceCount==0) // end of default argument { if (current->argList->getLast()) { - current->argList->getLast()->defval=g_defVal.stripWhiteSpace(); + current->argList->getLast()->defval=QCString(g_defVal.data()).stripWhiteSpace(); } - if (*yytext == ')') + if (*yytext != ',') current->args = argListToString(current->argList); BEGIN(FunctionParams); } else // continue { - if (*yytext == ')')g_braceCount--; + if (*yytext != ',')g_braceCount--; g_defVal+=*yytext; } } - . { - g_defVal+=*yytext; - } + "'" { + g_defVal+=*yytext; + g_copyString=&g_defVal; + g_stringContext=FunctionParamDefVal; + BEGIN( SingleQuoteString ); + } + "\"" { + g_defVal+=*yytext; + g_copyString=&g_defVal; + g_stringContext=FunctionParamDefVal; + BEGIN( DoubleQuoteString ); + } \n { g_defVal+=*yytext; incLineNr(); } + . { + g_defVal+=*yytext; + } } -- cgit v0.12 From eb72534ade8b9598806fc7e7b08374bd43bb44f3 Mon Sep 17 00:00:00 2001 From: albert-github Date: Mon, 5 Mar 2018 13:46:34 +0100 Subject: Bug 788940 - Bad handling of Python class members when a class declaration line contains a comment Made comments possible after a class declaration. --- src/pyscanner.l | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/pyscanner.l b/src/pyscanner.l index 9c21d41..37fd71d 100644 --- a/src/pyscanner.l +++ b/src/pyscanner.l @@ -1168,13 +1168,17 @@ STARTDOCSYMS "##" current->program+=yytext; BEGIN(TripleComment); } - {TRISINGLEQUOTE} { // start of a comment block initTriSingleQuoteBlock(); current->program+=yytext; BEGIN(TripleComment); } - + {STARTDOCSYMS}[#]* { // start of a special comment + initSpecialBlock(); + BEGIN(SpecialComment); + } + {POUNDCOMMENT} { // ignore comment with just one # + } ^{BB} { current->program+=yytext; //current->startLine = yyLineNr; @@ -1187,7 +1191,6 @@ STARTDOCSYMS "##" } ""/({NONEMPTY}|{EXPCHAR}) { - // Just pushback an empty class, and // resume parsing the body. newEntry(); -- cgit v0.12 From 89f808f75f7d39962a0b9dba4f479b5c6d6d9a24 Mon Sep 17 00:00:00 2001 From: albert-github Date: Tue, 6 Mar 2018 14:33:22 +0100 Subject: Bug 743539 - Field with name "internal" confuses documentation builder. internal is not a Java reserved word / keyword but was handled as such. --- src/code.l | 1 + src/scanner.l | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/code.l b/src/code.l index d7d5d74..1b86a62 100644 --- a/src/code.l +++ b/src/code.l @@ -2415,6 +2415,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" g_prefixed_with_this_keyword = TRUE; } {KEYWORD}/([^a-z_A-Z0-9]) { + if (g_insideJava && qstrcmp("internal",yytext) ==0) REJECT; startFontClass("keyword"); codifyLines(yytext); if (QCString(yytext)=="typedef") diff --git a/src/scanner.l b/src/scanner.l index 08a5e52..3a6eac0 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -2382,10 +2382,6 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { current->protection = Protected; } - else if (javaLike && qstrcmp(yytext,"internal")==0) - { - current->protection = Package; - } else if (javaLike && qstrcmp(yytext,"private")==0) { current->protection = Private; -- cgit v0.12 From ec0e5078b3a9db1f24079257287f7aee9e721093 Mon Sep 17 00:00:00 2001 From: albert-github Date: Tue, 6 Mar 2018 16:58:30 +0100 Subject: Small documentation corrections --- doc/arch.doc | 4 ++-- doc/commands.doc | 2 +- doc/customize.doc | 4 ++-- doc/docblocks.doc | 8 ++++---- doc/doxygen_usage.doc | 4 ++-- doc/extsearch.doc | 4 ++-- doc/faq.doc | 8 ++++---- doc/formulas.doc | 2 +- doc/install.doc | 4 ++-- doc/markdown.doc | 2 +- doc/preprocessing.doc | 4 ++-- doc/searching.doc | 10 +++++----- doc/starting.doc | 2 +- doc/trouble.doc | 2 +- src/config.xml | 10 +++++----- 15 files changed, 35 insertions(+), 35 deletions(-) diff --git a/doc/arch.doc b/doc/arch.doc index e5fbbdc..4032c66 100644 --- a/doc/arch.doc +++ b/doc/arch.doc @@ -41,14 +41,14 @@ available through the global functions \c Config_getXXX(), where \c XXX is the type of the option. The argument of these function is a string naming the option as it appears in the configuration file. For instance: \c Config_getBool("GENERATE_TESTLIST") returns a reference to a boolean -value that is \c TRUE if the test list was enabled in the config file. +value that is \c TRUE if the test list was enabled in the configuration file. The function \c readConfiguration() in \c src/doxygen.cpp reads the command line options and then calls the configuration parser.

C Preprocessor

-The input files mentioned in the config file are (by default) fed to the +The input files mentioned in the configuration file are (by default) fed to the C Preprocessor (after being piped through a user defined filter if available). The way the preprocessor works differs somewhat from a standard C Preprocessor. diff --git a/doc/commands.doc b/doc/commands.doc index 12b85db..1c7e7cf 100644 --- a/doc/commands.doc +++ b/doc/commands.doc @@ -697,7 +697,7 @@ Structural indicators command are considered to be internal as well. Only a new section at the same level will end the fragment that is considered internal. - You can use \ref cfg_internal_docs "INTERNAL_DOCS" in the config file + You can use \ref cfg_internal_docs "INTERNAL_DOCS" in the configuration file to show (\c YES) or hide (\c NO) the internal documentation. \sa section \ref cmdendinternal "\\endinternal". diff --git a/doc/customize.doc b/doc/customize.doc index 9ef3891..e2d53db 100644 --- a/doc/customize.doc +++ b/doc/customize.doc @@ -114,7 +114,7 @@ This will create 3 files: referencing those extra files via \ref cfg_html_extra_stylesheet "HTML_EXTRA_STYLESHEET". -You should edit these files and then reference them from the config file. +You should edit these files and then reference them from the configuration file. - \ref cfg_html_header "HTML_HEADER" = \c header.html - \ref cfg_html_footer "HTML_FOOTER" = \c footer.html - \ref cfg_html_extra_stylesheet "HTML_EXTRA_STYLESHEET" = \c my_customdoxygen.css @@ -158,7 +158,7 @@ doxygen -l optionally the name of the layout file can be specified, if omitted \c DoxygenLayout.xml will be used. -The next step is to mention the layout file in the config file +The next step is to mention the layout file in the configuration file \verbatim LAYOUT_FILE = DoxygenLayout.xml \endverbatim diff --git a/doc/docblocks.doc b/doc/docblocks.doc index 81cfdd0..e72ce95 100644 --- a/doc/docblocks.doc +++ b/doc/docblocks.doc @@ -293,7 +293,7 @@ The brief descriptions are included in the member overview of a class, namespace or file and are printed using a small italic font (this description can be hidden by setting \ref cfg_brief_member_desc "BRIEF_MEMBER_DESC" to \c NO in -the config file). By default the brief descriptions become the first +the configuration file). By default the brief descriptions become the first sentence of the detailed descriptions (but this can be changed by setting the \ref cfg_repeat_brief "REPEAT_BRIEF" tag to \c NO). Both the brief and the detailed descriptions are optional @@ -473,7 +473,7 @@ Here is the same example again but now using doxygen style comments: Since python looks more like Java than like C or C++, you should set \ref cfg_optimize_output_java "OPTIMIZE_OUTPUT_JAVA" to \c YES in the -config file. +configuration file. \subsection vhdlblocks Comment blocks in VHDL @@ -503,7 +503,7 @@ Here is an example VHDL file with doxygen comments: To get proper looking output you need to set \ref cfg_optimize_output_vhdl "OPTIMIZE_OUTPUT_VHDL" to \c YES in the -config file. This will also affect a number of other settings. When they +configuration file. This will also affect a number of other settings. When they were not already set correctly doxygen will produce a warning telling which settings where overruled. @@ -595,7 +595,7 @@ before the command. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testing/dtd/xhtml-special.ent b/testing/dtd/xhtml-special.ent new file mode 100755 index 0000000..ca358b2 --- /dev/null +++ b/testing/dtd/xhtml-special.ent @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testing/dtd/xhtml-symbol.ent b/testing/dtd/xhtml-symbol.ent new file mode 100755 index 0000000..63c2abf --- /dev/null +++ b/testing/dtd/xhtml-symbol.ent @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testing/dtd/xhtml1-strict.dtd b/testing/dtd/xhtml1-strict.dtd new file mode 100755 index 0000000..2927b9e --- /dev/null +++ b/testing/dtd/xhtml1-strict.dtd @@ -0,0 +1,978 @@ + + + + + +%HTMLlat1; + + +%HTMLsymbol; + + +%HTMLspecial; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testing/dtd/xhtml1-transitional.dtd b/testing/dtd/xhtml1-transitional.dtd new file mode 100755 index 0000000..628f27a --- /dev/null +++ b/testing/dtd/xhtml1-transitional.dtd @@ -0,0 +1,1201 @@ + + + + + +%HTMLlat1; + + +%HTMLsymbol; + + +%HTMLspecial; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testing/runtests.py b/testing/runtests.py index 83647c6..d1ce5fd 100644 --- a/testing/runtests.py +++ b/testing/runtests.py @@ -30,6 +30,19 @@ class Tester: return (True,'Difference between generated output and reference:\n%s' % diff) return (False,'') + def cleanup_xmllint(self,errmsg): + msg = errmsg.split('\n') + rtnmsg = "" + for o in msg: + if (o): + if (o.startswith("I/O error : Attempt")): + pass + else: + if (rtnmsg): + rtnmsg += '\n' + rtnmsg += o + return rtnmsg + def get_config(self): config = {} with open(self.args.inputdir+'/'+self.test,'r') as f: @@ -50,13 +63,25 @@ class Tester: os.mkdir(self.test_out) shutil.copy(self.args.inputdir+'/Doxyfile',self.test_out) with open(self.test_out+'/Doxyfile','a') as f: - print('INPUT=%s/%s' % (self.args.inputdir,self.test), file=f) - print('STRIP_FROM_PATH=%s' % self.args.inputdir, file=f) - print('XML_OUTPUT=%s/out' % self.test_out, file=f) - print('EXAMPLE_PATH=%s' % self.args.inputdir, file=f) if 'config' in self.config: for option in self.config['config']: print(option, file=f) + print('INPUT=%s/%s' % (self.args.inputdir,self.test), file=f) + print('STRIP_FROM_PATH=%s' % self.args.inputdir, file=f) + if (self.args.xml): + print('GENERATE_XML=YES', file=f) + print('XML_OUTPUT=%s/out' % self.test_out, file=f) + else: + print('GENERATE_XML=NO', file=f) + if (self.args.xhtml): + print('GENERATE_HTML=YES', file=f) + # HTML_OUTPUT can also be set locally + print('HTML_OUTPUT=%s/html' % self.test_out, file=f) + print('HTML_FILE_EXTENSION=.xhtml', file=f) + if (self.args.pdf): + print('GENERATE_LATEX=YES', file=f) + print('LATEX_OUTPUT=%s/latex' % self.test_out, file=f) + print('EXAMPLE_PATH=%s' % self.args.inputdir, file=f) if 'check' not in self.config or not self.config['check']: print('Test doesn\'t specify any files to check') @@ -64,10 +89,14 @@ class Tester: # run doxygen if (sys.platform == 'win32'): - redir=' > nul:' + redir=' > nul:' else: - redir=' 2> /dev/null' - if os.system('%s %s/Doxyfile %s' % (self.args.doxygen,self.test_out, redir))!=0: + redir=' 2> /dev/null > /dev/null' + + if (self.args.noredir): + redir='' + + if os.system('%s %s/Doxyfile %s' % (self.args.doxygen,self.test_out,redir))!=0: print('Error: failed to run %s on %s/Doxyfile' % (self.args.doxygen,self.test_out)); sys.exit(1) @@ -98,32 +127,92 @@ class Tester: # check the relevant files of a doxygen run with the reference material def perform_test(self,testmgr): + if (sys.platform == 'win32'): + redir=' > nul:' + separ='&' + else: + redir=' 2> /dev/null' + separ=';' + + if (self.args.noredir): + redir='' + + failed_xml=False + failed_html=False + failed_latex=False + msg = () # look for files to check against the reference - if 'check' in self.config: - for check in self.config['check']: - check_file='%s/out/%s' % (self.test_out,check) - # check if the file we need to check is actually generated - if not os.path.isfile(check_file): - testmgr.ok(False,self.test_name,msg='Non-existing file %s after \'check:\' statement' % check_file) - return - # convert output to canonical form - data = os.popen('%s --format --noblanks --nowarning %s' % (self.args.xmllint,check_file)).read() - if data: - # strip version - data = re.sub(r'xsd" version="[0-9.-]+"','xsd" version=""',data).rstrip('\n') - else: - testmgr.ok(False,self.test_name,msg='Failed to run %s on the doxygen output file %s' % (self.args.xmllint,self.test_out)) - return - out_file='%s/%s' % (self.test_out,check) - with open(out_file,'w') as f: - print(data,file=f) - ref_file='%s/%s/%s' % (self.args.inputdir,self.test_id,check) - (failed,msg) = self.compare_ok(out_file,ref_file,self.test_name) - if failed: - testmgr.ok(False,self.test_name,msg) - return - shutil.rmtree(self.test_out,ignore_errors=True) + if self.args.xml: + failed_xml=True + if 'check' in self.config: + for check in self.config['check']: + check_file='%s/out/%s' % (self.test_out,check) + # check if the file we need to check is actually generated + if not os.path.isfile(check_file): + msg += ('Non-existing file %s after \'check:\' statement' % check_file,) + break + # convert output to canonical form + data = os.popen('%s --format --noblanks --nowarning %s' % (self.args.xmllint,check_file)).read() + if data: + # strip version + data = re.sub(r'xsd" version="[0-9.-]+"','xsd" version=""',data).rstrip('\n') + else: + msg += ('Failed to run %s on the doxygen output file %s' % (self.args.xmllint,self.test_out),) + break + out_file='%s/%s' % (self.test_out,check) + with open(out_file,'w') as f: + print(data,file=f) + ref_file='%s/%s/%s' % (self.args.inputdir,self.test_id,check) + (failed_xml,xml_msg) = self.compare_ok(out_file,ref_file,self.test_name) + if failed_xml: + msg+= (xml_msg,) + break + if not failed_xml and not self.args.keep: + xml_output='%s/out' % self.test_out + shutil.rmtree(xml_output,ignore_errors=True) + + if (self.args.xhtml): + html_output='%s/html' % self.test_out + if (sys.platform == 'win32'): + redirx=' 2> %s/temp >nul:'%html_output + else: + redirx='2>%s/temp >/dev/null'%html_output + exe_string = '%s --path dtd --nonet --postvalid %s/*xhtml %s %s ' % (self.args.xmllint,html_output,redirx,separ) + exe_string += 'more "%s/temp"' % (html_output) + failed_html=False + xmllint_out = os.popen(exe_string).read() + xmllint_out = self.cleanup_xmllint(xmllint_out) + if xmllint_out: + msg += (xmllint_out,) + failed_html=True + elif not self.args.keep: + shutil.rmtree(html_output,ignore_errors=True) + if (self.args.pdf): + failed_latex=False + latex_output='%s/latex' % self.test_out + if (sys.platform == 'win32'): + redirl='>nul: 2>temp' + else: + redirl='>/dev/null 2>temp' + exe_string = 'cd %s %s echo "q" | make %s %s' % (latex_output,separ,redirl,separ) + exe_string += 'more temp' + latex_out = os.popen(exe_string).read() + if latex_out.find("Error")!=-1: + msg += ("PDF generation failed\n For a description of the problem see 'refman.log' in the latex directory of this test",) + failed_html=True + elif open(latex_output + "/refman.log",'r').read().find("Emergency stop")!= -1: + msg += ("PDF generation failed\n For a description of the problem see 'refman.log' in the latex directory of this test",) + failed_html=True + elif not self.args.keep: + shutil.rmtree(latex_output,ignore_errors=True) + + if failed_xml or failed_html or failed_latex: + testmgr.ok(False,self.test_name,msg) + return + testmgr.ok(True,self.test_name) + if not self.args.keep: + shutil.rmtree(self.test_out,ignore_errors=True) def run(self,testmgr): if self.update: @@ -138,6 +227,8 @@ class TestManager: self.num_tests = len(tests) self.count=1 self.passed=0 + if self.args.xhtml: + self.prepare_dtd() print('1..%d' % self.num_tests) def ok(self,result,test_name,msg='Ok'): @@ -147,8 +238,9 @@ class TestManager: else: print('not ok %s - %s' % (self.count,test_name)) print('-------------------------------------') - print(msg) - print('-------------------------------------') + for o in msg: + print(o) + print('-------------------------------------') self.count = self.count + 1 def result(self): @@ -162,27 +254,56 @@ class TestManager: for test in self.tests: tester = Tester(self.args,test) tester.run(self) - return 0 if self.args.updateref else self.result() + res=self.result() + if self.args.xhtml and not res and not self.args.keep: + shutil.rmtree("dtd",ignore_errors=True) + return 0 if self.args.updateref else res + + def prepare_dtd(self): + shutil.rmtree("dtd",ignore_errors=True) + shutil.copytree(self.args.inputdir+"/dtd", "dtd") def main(): # argument handling parser = argparse.ArgumentParser(description='run doxygen tests') - parser.add_argument('--updateref',help='update the reference data for a test',action="store_true") - parser.add_argument('--doxygen',nargs='?',default='doxygen',help='path/name of the doxygen executable') - parser.add_argument('--xmllint',nargs='?',default='xmllint',help='path/name of the xmllint executable') - parser.add_argument('--id',nargs='+',dest='ids',action='append',type=int,help='id of the test to perform') - parser.add_argument('--all',help='perform all tests',action="store_true") - parser.add_argument('--inputdir',nargs='?',default='.',help='input directory containing the tests') - parser.add_argument('--outputdir',nargs='?',default='.',help='output directory to write the doxygen output to') + parser.add_argument('--updateref',help= + 'update the reference files. Should be used in combination with -id to ' + 'update the reference file(s) for the given test',action="store_true") + parser.add_argument('--doxygen',nargs='?',default='doxygen',help= + 'path/name of the doxygen executable') + parser.add_argument('--xmllint',nargs='?',default='xmllint',help= + 'path/name of the xmllint executable') + parser.add_argument('--id',nargs='+',dest='ids',action='append',type=int,help= + 'run test with number n only (the option may be specified run test with ' + 'number n only (the option may be specified') + parser.add_argument('--all',help= + 'can be used in combination with -updateref to update the reference files ' + 'for all tests.',action="store_true") + parser.add_argument('--inputdir',nargs='?',default='.',help= + 'input directory containing the tests') + parser.add_argument('--outputdir',nargs='?',default='.',help= + 'output directory to write the doxygen output to') + parser.add_argument('--noredir',help= + 'disable redirection of doxygen warnings',action="store_true") + parser.add_argument('--xml',help='create xml output and check', + action="store_true") + parser.add_argument('--xhtml',help= + 'create xhtml output and check with xmllint',action="store_true") + parser.add_argument('--pdf',help='create LaTeX output and create pdf from it', + action="store_true") + parser.add_argument('--keep',help='keep result directories', + action="store_true") args = parser.parse_args() - # sanity check + # sanity check + if (not args.xml) and (not args.pdf) and (not args.xhtml): + args.xml=True if (not args.updateref is None) and (args.ids is None) and (args.all is None): parser.error('--updateref requires either --id or --all') starting_directory = os.getcwd() os.chdir(args.inputdir) - # find the tests to run + # find the tests to run if args.ids: # test ids are given by user tests = [] for id in list(itertools.chain.from_iterable(args.ids)): -- cgit v0.12 From 95a6451107f8964b1c2290e2f4e9761a64be124b Mon Sep 17 00:00:00 2001 From: albert-github Date: Tue, 3 Apr 2018 19:48:15 +0200 Subject: Create test possibilities for xhtml and pdf output Regression of default output (INPUT setting was overruled). --- testing/runtests.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testing/runtests.py b/testing/runtests.py index d1ce5fd..a714cd8 100644 --- a/testing/runtests.py +++ b/testing/runtests.py @@ -63,11 +63,12 @@ class Tester: os.mkdir(self.test_out) shutil.copy(self.args.inputdir+'/Doxyfile',self.test_out) with open(self.test_out+'/Doxyfile','a') as f: + print('INPUT=%s/%s' % (self.args.inputdir,self.test), file=f) + print('STRIP_FROM_PATH=%s' % self.args.inputdir, file=f) + print('EXAMPLE_PATH=%s' % self.args.inputdir, file=f) if 'config' in self.config: for option in self.config['config']: print(option, file=f) - print('INPUT=%s/%s' % (self.args.inputdir,self.test), file=f) - print('STRIP_FROM_PATH=%s' % self.args.inputdir, file=f) if (self.args.xml): print('GENERATE_XML=YES', file=f) print('XML_OUTPUT=%s/out' % self.test_out, file=f) @@ -81,7 +82,6 @@ class Tester: if (self.args.pdf): print('GENERATE_LATEX=YES', file=f) print('LATEX_OUTPUT=%s/latex' % self.test_out, file=f) - print('EXAMPLE_PATH=%s' % self.args.inputdir, file=f) if 'check' not in self.config or not self.config['check']: print('Test doesn\'t specify any files to check') -- cgit v0.12 From afecea64c225ec3c8ef9c84235d9fe091af588ca Mon Sep 17 00:00:00 2001 From: albert-github Date: Mon, 9 Apr 2018 13:56:47 +0200 Subject: Correcting "Definition at line @0 of file @1." In the LaTeX and RTF documentation where the filename should be presented before the linenumber (e.g. Chinese, Japanese) in the sentence "Definition at line @0 of file @1." neither was shown, the HTML version was correct. --- src/definition.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/definition.cpp b/src/definition.cpp index ff30429..92baf0c 100644 --- a/src/definition.cpp +++ b/src/definition.cpp @@ -1034,15 +1034,15 @@ void Definition::writeSourceDef(OutputList &ol,const char *) ol.pushGeneratorState(); ol.disable(OutputGenerator::Man); - if (!latexSourceCode) + ol.disableAllBut(OutputGenerator::Html); + if (latexSourceCode) { - ol.disable(OutputGenerator::Latex); + ol.enable(OutputGenerator::Latex); } - if (!rtfSourceCode) + if (rtfSourceCode) { - ol.disable(OutputGenerator::RTF); + ol.enable(OutputGenerator::RTF); } - ol.disableAllBut(OutputGenerator::Html); // write line link (HTML only) ol.writeObjectLink(0,fn,anchorStr,lineStr); ol.enableAll(); -- cgit v0.12 From 55bdda94dc8661dc740e26e6fb91beb7e2bb7ec7 Mon Sep 17 00:00:00 2001 From: albert-github Date: Mon, 9 Apr 2018 14:03:06 +0200 Subject: Correction internal documentation Small correcting to remove some messages about wrong parameter documentation in doxygen internal documentation. --- src/context.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/context.cpp b/src/context.cpp index 896c4e0..4584920 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -246,7 +246,6 @@ class PropertyMapper /** Add a property to the map * @param[in] name The name of the property to add. - * @param[in] obj The object handling access to the property. * @param[in] handle The method to call when the property is accessed. */ void addProperty(const char *name,typename PropertyFunc::Handler handle) @@ -262,6 +261,7 @@ class PropertyMapper } /** Gets the value of a property. + * @param[in] obj The object handling access to the property. * @param[in] name The name of the property. * @returns A variant representing the properties value or an * invalid variant if it was not found. -- cgit v0.12 From 66f9f6ec07f29fb737b0d0fe11072ea156581576 Mon Sep 17 00:00:00 2001 From: albert-github Date: Mon, 9 Apr 2018 14:12:03 +0200 Subject: XHTML image tag mandatory alt attribute The alt attribute is mandatory for the image tag, it is possible to have it written out with an empty string. In case with the image tag there is no alt attribute the empty string alt attribute is added. --- src/htmldocvisitor.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp index 8b6d26c..6a9c142 100644 --- a/src/htmldocvisitor.cpp +++ b/src/htmldocvisitor.cpp @@ -126,21 +126,29 @@ static bool mustBeOutsideParagraph(DocNode *n) return FALSE; } -static QString htmlAttribsToString(const HtmlAttribList &attribs) +static QString htmlAttribsToString(const HtmlAttribList &attribs, const bool img_tag = FALSE) { QString result; HtmlAttribListIterator li(attribs); HtmlAttrib *att; + bool alt_set = FALSE; + for (li.toFirst();(att=li.current());++li) { if (!att->value.isEmpty()) // ignore attribute without values as they - // are not XHTML compliant + // are not XHTML compliant, with the exception + // of the alt attribute with the img tag { result+=" "; result+=att->name; result+="=\""+convertToXML(att->value)+"\""; + if (att->name == "alt") alt_set = TRUE; } } + if (!alt_set && img_tag) + { + result+=" alt=\"\""; + } return result; } @@ -1521,7 +1529,7 @@ void HtmlDocVisitor::visitPre(DocImage *img) else { m_t << "relPath()) << "\"" - << sizeAttribs << htmlAttribsToString(img->attribs()) + << sizeAttribs << htmlAttribsToString(img->attribs(), TRUE) << "/>" << endl; } } -- cgit v0.12 From fe7e597a172fa08a075ac10bbefc572a785e4c0d Mon Sep 17 00:00:00 2001 From: albert-github Date: Tue, 10 Apr 2018 12:46:44 +0200 Subject: Bug 303020 - Missing warning of undocumented member in member group Removed restrictions that functions / variables / enums ... in a \name command were executed from the test. (Note: In case of functions the arguments were tested or presence). --- src/memberdef.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/memberdef.cpp b/src/memberdef.cpp index 01f4d8d..4328437 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -3212,7 +3212,10 @@ QCString MemberDef::memberTypeName() const void MemberDef::warnIfUndocumented() { - if (m_impl->memberGroup) return; + /* + * Removed bug_303020: + * if (m_impl->memberGroup) return; + */ ClassDef *cd = getClassDef(); NamespaceDef *nd = getNamespaceDef(); FileDef *fd = getFileDef(); -- cgit v0.12 From 84c791d75dd1e9026cbbc1a338316656b0c03896 Mon Sep 17 00:00:00 2001 From: albert-github Date: Tue, 10 Apr 2018 13:21:56 +0200 Subject: Consistency of Index name in LaTeX output The name of the index is used on a number of places, in the Contents and the Bookmarks the name as used in the \addcontentsline is used and in the chapter with the index the name as specified in the \indexname is used. The \indexname is set by the language package and the name in the \addcontentsline the name as used in the doxygen translator is used, this can lead to inconsistencies (e.g. Slovak language Register versus Index). The approach has be made uniform here by using \indexname on bot places. --- src/latexgen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/latexgen.cpp b/src/latexgen.cpp index 1511dcb..9b07fe6 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -748,7 +748,7 @@ static void writeDefaultFooter(FTextStream &t) t << "\\newpage\n" "\\phantomsection\n" "\\clearemptydoublepage\n" - "\\addcontentsline{toc}{" << unit << "}{" << theTranslator->trRTFGeneralIndex() << "}\n" + "\\addcontentsline{toc}{" << unit << "}{\\indexname}\n" "\\printindex\n" "\n" "\\end{document}\n"; -- cgit v0.12 From 7a8e1182ba11369f11325d75af552ad7467b1e81 Mon Sep 17 00:00:00 2001 From: albert-github Date: Wed, 11 Apr 2018 12:29:06 +0200 Subject: LaTeX with verbatim part inside a table Doxygen test 54, when generating LaTeX / PDF, gave the error message: Runaway argument? Second paragraph of the param description. \end {DoxyVerb} \\ \hline \ETC. ! Paragraph ended before \verbatim@ was complete. \par l.41 \end{DoxyParams} The tabu package documentation (and Stack Exchange LaTeX) give some hints in to the problem about the verbatim command in the different environments and has been implemented here for the longtabu table. --- templates/latex/doxygen.sty | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/templates/latex/doxygen.sty b/templates/latex/doxygen.sty index e457acc..02ec07a 100644 --- a/templates/latex/doxygen.sty +++ b/templates/latex/doxygen.sty @@ -11,6 +11,7 @@ \RequirePackage[table]{xcolor} \RequirePackage{longtable} \RequirePackage{tabu} +\RequirePackage{fancyvrb} \RequirePackage{tabularx} \RequirePackage{multirow} @@ -273,10 +274,10 @@ \tabulinesep=1mm% \par% \ifthenelse{\equal{#1}{}}% - {\begin{longtabu} spread 0pt [l]{|X[-1,l]|X[-1,l]|}}% name + description + {\begin{longtabu*} spread 0pt [l]{|X[-1,l]|X[-1,l]|}}% name + description {\ifthenelse{\equal{#1}{1}}% - {\begin{longtabu} spread 0pt [l]{|X[-1,l]|X[-1,l]|X[-1,l]|}}% in/out + name + desc - {\begin{longtabu} spread 0pt [l]{|X[-1,l]|X[-1,l]|X[-1,l]|X[-1,l]|}}% in/out + type + name + desc + {\begin{longtabu*} spread 0pt [l]{|X[-1,l]|X[-1,l]|X[-1,l]|}}% in/out + name + desc + {\begin{longtabu*} spread 0pt [l]{|X[-1,l]|X[-1,l]|X[-1,l]|X[-1,l]|}}% in/out + type + name + desc } \multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #2}\\[1ex]% \hline% @@ -285,7 +286,7 @@ \hline% \endhead% }{% - \end{longtabu}% + \end{longtabu*}% \vspace{6pt}% } @@ -293,7 +294,7 @@ \newenvironment{DoxyFields}[1]{% \tabulinesep=1mm% \par% - \begin{longtabu} spread 0pt [l]{|X[-1,r]|X[-1,l]|X[-1,l]|}% + \begin{longtabu*} spread 0pt [l]{|X[-1,r]|X[-1,l]|X[-1,l]|}% \multicolumn{3}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]% \hline% \endfirsthead% @@ -301,7 +302,7 @@ \hline% \endhead% }{% - \end{longtabu}% + \end{longtabu*}% \vspace{6pt}% } @@ -309,7 +310,7 @@ \newenvironment{DoxyEnumFields}[1]{% \tabulinesep=1mm% \par% - \begin{longtabu} spread 0pt [l]{|X[-1,r]|X[-1,l]|}% + \begin{longtabu*} spread 0pt [l]{|X[-1,r]|X[-1,l]|}% \multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]% \hline% \endfirsthead% @@ -317,7 +318,7 @@ \hline% \endhead% }{% - \end{longtabu}% + \end{longtabu*}% \vspace{6pt}% } @@ -331,7 +332,7 @@ \newenvironment{DoxyRetVals}[1]{% \tabulinesep=1mm% \par% - \begin{longtabu} spread 0pt [l]{|X[-1,r]|X[-1,l]|}% + \begin{longtabu*} spread 0pt [l]{|X[-1,r]|X[-1,l]|}% \multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]% \hline% \endfirsthead% @@ -339,7 +340,7 @@ \hline% \endhead% }{% - \end{longtabu}% + \end{longtabu*}% \vspace{6pt}% } @@ -347,7 +348,7 @@ \newenvironment{DoxyExceptions}[1]{% \tabulinesep=1mm% \par% - \begin{longtabu} spread 0pt [l]{|X[-1,r]|X[-1,l]|}% + \begin{longtabu*} spread 0pt [l]{|X[-1,r]|X[-1,l]|}% \multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]% \hline% \endfirsthead% @@ -355,7 +356,7 @@ \hline% \endhead% }{% - \end{longtabu}% + \end{longtabu*}% \vspace{6pt}% } @@ -363,7 +364,7 @@ \newenvironment{DoxyTemplParams}[1]{% \tabulinesep=1mm% \par% - \begin{longtabu} spread 0pt [l]{|X[-1,r]|X[-1,l]|}% + \begin{longtabu*} spread 0pt [l]{|X[-1,r]|X[-1,l]|}% \multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]% \hline% \endfirsthead% @@ -371,7 +372,7 @@ \hline% \endhead% }{% - \end{longtabu}% + \end{longtabu*}% \vspace{6pt}% } @@ -439,8 +440,8 @@ \newcommand{\PBS}[1]{\let\temp=\\#1\let\\=\temp}% \newenvironment{TabularC}[1]% {\tabulinesep=1mm -\begin{longtabu} spread 0pt [c]{*#1{|X[-1]}|}}% -{\end{longtabu}\par}% +\begin{longtabu*} spread 0pt [c]{*#1{|X[-1]}|}}% +{\end{longtabu*}\par}% \newenvironment{TabularNC}[1]% {\begin{tabu} spread 0pt [l]{*#1{|X[-1]}|}}% -- cgit v0.12 From 5a9bfc176eb3da266f44bd5cb0b38975c812e49c Mon Sep 17 00:00:00 2001 From: albert-github Date: Thu, 12 Apr 2018 15:51:28 +0200 Subject: Bug 740046 - Negative sign in -Foo::Bar ruins hyperlink in generated output Excluded digits and '+' sign and '-' sign from determination of Words. --- src/doctokenizer.l | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/doctokenizer.l b/src/doctokenizer.l index 90a8c55..fe49ab2 100644 --- a/src/doctokenizer.l +++ b/src/doctokenizer.l @@ -387,7 +387,8 @@ LNKWORD2 (({SCOPEPRE}*"operator"{OPMASK})|({SCOPEPRE}"operator"{OPMASKOPT})|((" LNKWORD3 ([0-9a-z_A-Z\-]+("/"|"\\"))*[0-9a-z_A-Z\-]+("."[0-9a-z_A-Z]+)+ CHARWORDQ [^ \t\n\r\\@<>()\[\]:;\?{}&%$#,."='] ESCWORD ("%"{ID}(("::"|"."){ID})*)|("%'") -WORD1 {ESCWORD}|{CHARWORDQ}+|"{"|"}"|"'\"'"|("\""[^"\n]*\n?[^"\n]*"\"") +CHARWORDQ1 [^ \-+0-9\t\n\r\\@<>()\[\]:;\?{}&%$#,."='] +WORD1 {ESCWORD}|{CHARWORDQ1}+|"{"|"}"|"'\"'"|("\""[^"\n]*\n?[^"\n]*"\"") WORD2 "."|","|"("|")"|"["|"]"|":"|";"|"\?"|"="|"'" WORD1NQ {ESCWORD}|{CHARWORDQ}+|"{"|"}" WORD2NQ "."|","|"("|")"|"["|"]"|":"|";"|"\?"|"="|"'" @@ -696,6 +697,7 @@ REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} } /********* patterns for normal words ******************/ +[\-+0-9] | {WORD1} | {WORD2} { /* function call */ if (yytext[0]=='%') // strip % if present @@ -931,6 +933,7 @@ REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} g_token->name = yytext; return TK_WORD; } +[\-+0-9] | {WORD1} | {WORD2} { /* word */ if (yytext[0]=='%') // strip % if present -- cgit v0.12 From b1792d19afd245f33667e6170b9f08a8528e07f8 Mon Sep 17 00:00:00 2001 From: Christoph Lipka Date: Sat, 14 Apr 2018 10:14:05 +0200 Subject: Bug 795252 - Broken extension test in FileDef::generateSourceFile() --- src/filedef.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/filedef.cpp b/src/filedef.cpp index 2cfe37a..74c4c67 100644 --- a/src/filedef.cpp +++ b/src/filedef.cpp @@ -1425,8 +1425,7 @@ bool FileDef::generateSourceFile() const (sourceBrowser || (verbatimHeaders && guessSection(name())==Entry::HEADER_SEC) ) && - extension!=".doc" && extension!=".txt" && extension!=".dox" && - extension!=".md" && name().right(9)!=".markdown"; + !isDocumentationFile(); } -- cgit v0.12 From 5d79d65df3b66554c8e9630fd3bea322c3e36f0d Mon Sep 17 00:00:00 2001 From: Christoph Lipka Date: Sat, 14 Apr 2018 11:37:58 +0200 Subject: Include "empty" directories in the documentation if they contain a `.dox` file (or similar) documenting the directory itself. --- src/dirdef.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dirdef.cpp b/src/dirdef.cpp index b247ba7..6631ed7 100644 --- a/src/dirdef.cpp +++ b/src/dirdef.cpp @@ -930,14 +930,14 @@ void buildDirectories() for (;(fd=fni.current());++fni) { //printf("buildDirectories %s\n",fd->name().data()); - if (fd->getReference().isEmpty() && !fd->isDocumentationFile()) + if (fd->getReference().isEmpty()) { DirDef *dir; if ((dir=Doxygen::directories->find(fd->getPath()))==0) // new directory { dir = DirDef::mergeDirectoryInTree(fd->getPath()); } - if (dir) dir->addFile(fd); + if (dir && !fd->isDocumentationFile()) dir->addFile(fd); } else { -- cgit v0.12 From 99a836218ca4e20862d3f816361c4586b45560ee Mon Sep 17 00:00:00 2001 From: "luz.paz" Date: Wed, 25 Apr 2018 13:32:21 -0400 Subject: Misc. typos Found via `codespell` --- addon/doxmlparser/src/dochandler.h | 2 +- src/cite.cpp | 2 +- src/classdef.cpp | 4 ++-- src/classdef.h | 2 +- src/commentcnv.l | 4 ++-- src/condparser.cpp | 2 +- src/diagram.cpp | 2 +- src/docparser.h | 4 ++-- src/fortrancode.l | 4 ++-- src/memberdef.cpp | 4 ++-- src/util.cpp | 4 ++-- src/xmlgen.cpp | 2 +- vhdlparser/ErrorHandler.h | 2 +- vhdlparser/ParseException.cc | 2 +- vhdlparser/ParseException.h | 2 +- 15 files changed, 21 insertions(+), 21 deletions(-) diff --git a/addon/doxmlparser/src/dochandler.h b/addon/doxmlparser/src/dochandler.h index 4340dbd..59af4e3 100644 --- a/addon/doxmlparser/src/dochandler.h +++ b/addon/doxmlparser/src/dochandler.h @@ -571,7 +571,7 @@ class EMailHandler : public DocEMailImpl, public BaseHandler //----------------------------------------------------------------------------- -/* \brief Node representing a link to an URL +/* \brief Node representing a link to a URL * */ class ULinkHandler : public DocULinkImpl, public BaseHandler diff --git a/src/cite.cpp b/src/cite.cpp index f86350b..b17800f 100644 --- a/src/cite.cpp +++ b/src/cite.cpp @@ -268,7 +268,7 @@ void CiteDict::generatePage() const { if (!bibFile.isEmpty()) { - // bug_700510, multile times the same name were overwriting; creating new names + // bug_700510, multiple times the same name were overwriting; creating new names // also for names with spaces ++i; copyFile(bibFile,latexOutputDir + bibTmpFile + QCString().setNum(i) + ".bib"); diff --git a/src/classdef.cpp b/src/classdef.cpp index e1a80ce..4ce48a7 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -2687,7 +2687,7 @@ bool ClassDef::hasNonReferenceSuperClass() return found; } -/*! called from MemberDef::writeDeclaration() to (recusively) write the +/*! called from MemberDef::writeDeclaration() to (recursively) write the * definition of an anonymous struct, union or class. */ void ClassDef::writeDeclaration(OutputList &ol,MemberDef *md,bool inGroup, @@ -2873,7 +2873,7 @@ static bool isStandardFunc(MemberDef *md) } /*! - * recusively merges the `all members' lists of a class base + * recursively merges the `all members' lists of a class base * with that of this class. Must only be called for classes without * subclasses! */ diff --git a/src/classdef.h b/src/classdef.h index 23c5c5c..b169221 100644 --- a/src/classdef.h +++ b/src/classdef.h @@ -200,7 +200,7 @@ class ClassDef : public Definition MemberDef *getMemberByName(const QCString &) const; /** Returns TRUE iff \a bcd is a direct or indirect base class of this - * class. This function will recusively traverse all branches of the + * class. This function will recursively traverse all branches of the * inheritance tree. */ bool isBaseClass(ClassDef *bcd,bool followInstances,int level=0); diff --git a/src/commentcnv.l b/src/commentcnv.l index aca7300..89d2fea 100644 --- a/src/commentcnv.l +++ b/src/commentcnv.l @@ -294,12 +294,12 @@ void replaceComment(int offset); } else { - /* check for fixed format; we might have some conditional as part of multilene if like C<5 .and. & */ + /* check for fixed format; we might have some conditional as part of multiline if like C<5 .and. & */ if (isFixedForm && (g_col == 0)) { copyToOutput(yytext,(int)yyleng); g_nestingCount=0; - g_commentStack.clear(); /* to be on the save side */ + g_commentStack.clear(); /* to be on the safe side */ BEGIN(CComment); g_commentStack.push(new CommentCtx(g_lineNr)); } diff --git a/src/condparser.cpp b/src/condparser.cpp index 6c5d787..ab33ae3 100644 --- a/src/condparser.cpp +++ b/src/condparser.cpp @@ -283,7 +283,7 @@ bool CondParser::parseVar() } /** - * evaluate an operator for given valuess + * evaluate an operator for given values */ bool CondParser::evalOperator(int opId, bool lhs, bool rhs) { diff --git a/src/diagram.cpp b/src/diagram.cpp index 42792ad..667aa85 100644 --- a/src/diagram.cpp +++ b/src/diagram.cpp @@ -833,7 +833,7 @@ void TreeDiagram::drawConnectors(FTextStream &t,Image *image, } ++rit; di=rit.current(); } - // add last horizonal line and a vertical connection line + // add last horizontal line and a vertical connection line if (bitmap) { if (doBase) // base classes diff --git a/src/docparser.h b/src/docparser.h index 8fcbed6..d7390c2 100644 --- a/src/docparser.h +++ b/src/docparser.h @@ -277,7 +277,7 @@ class DocLinkedWord : public DocNode QCString m_tooltip; }; -/** Node representing an URL (or email address) */ +/** Node representing a URL (or email address) */ class DocURL : public DocNode { public: @@ -306,7 +306,7 @@ class DocLineBreak : public DocNode private: }; -/** Node representing a horizonal ruler */ +/** Node representing a horizontal ruler */ class DocHorRuler : public DocNode { public: diff --git a/src/fortrancode.l b/src/fortrancode.l index f491acb..ea74aa9 100644 --- a/src/fortrancode.l +++ b/src/fortrancode.l @@ -862,7 +862,7 @@ PREFIX ((NON_)?RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,4}((NON generateLink(*g_code,yytext); yy_pop_state(); } -({ACCESS_SPEC}|ABSTRACT|EXTENDS)/[,:( ] { //| variable deklaration +({ACCESS_SPEC}|ABSTRACT|EXTENDS)/[,:( ] { //| variable declaration startFontClass("keyword"); g_code->codify(yytext); endFontClass(); @@ -946,7 +946,7 @@ PREFIX ((NON_)?RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,4}((NON g_code->codify(yytext); endFontClass(); } -({TYPE_SPEC}|{ATTR_SPEC})/[,:( ] { //| variable deklaration +({TYPE_SPEC}|{ATTR_SPEC})/[,:( ] { //| variable declaration startFontClass("keywordtype"); g_code->codify(yytext); endFontClass(); diff --git a/src/memberdef.cpp b/src/memberdef.cpp index 4328437..0bd0701 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -101,7 +101,7 @@ static QCString addTemplateNames(const QCString &s,const QCString &n,const QCStr // ol.endParameterName(last==FALSE) // ... // ol.startParameterType(first=FALSE) -// ol.endParamtereType +// ol.endParameterType // ol.startParameterName // ol.endParameterName(last==TRUE) // ... @@ -571,7 +571,7 @@ class MemberDefImpl bool stat; // is it a static function? bool proto; // is it a prototype; bool docEnumValues; // is an enum with documented enum values. - bool annScope; // member is part of an annoymous scope + bool annScope; // member is part of an anonymous scope bool annUsed; bool hasCallGraph; bool hasCallerGraph; diff --git a/src/util.cpp b/src/util.cpp index 9100706..9762892 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -7917,7 +7917,7 @@ bool readInputFile(const char *fileName,BufStr &inBuf,bool filter,bool isSourceC int start=0; if (size>=2 && - ((inBuf.at(0)==-1 && inBuf.at(1)==-2) || // Litte endian BOM + ((inBuf.at(0)==-1 && inBuf.at(1)==-2) || // Little endian BOM (inBuf.at(0)==-2 && inBuf.at(1)==-1) // big endian BOM ) ) // UCS-2 encoded file @@ -8081,7 +8081,7 @@ QCString externalRef(const QCString &relPath,const QCString &ref,bool href) return result; } -/** Writes the intensity only bitmap representated by \a data as an image to +/** Writes the intensity only bitmap represented by \a data as an image to * directory \a dir using the colors defined by HTML_COLORSTYLE_*. */ void writeColoredImgData(const char *dir,ColoredImgDataItem data[]) diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp index 697a4d8..63fc8ad 100644 --- a/src/xmlgen.cpp +++ b/src/xmlgen.cpp @@ -175,7 +175,7 @@ static void writeCombineScript() " \n" " \n" " \n" - " \n" + " \n" " \n" " \n" " \n" diff --git a/vhdlparser/ErrorHandler.h b/vhdlparser/ErrorHandler.h index 55286b4..7500a5f 100644 --- a/vhdlparser/ErrorHandler.h +++ b/vhdlparser/ErrorHandler.h @@ -30,7 +30,7 @@ JAVACC_SIMPLE_STRING addUnicodeEscapes(JAVACC_STRING_TYPE str); // Called when the parser cannot continue parsing. // last - the last token successfully parsed. // unexpected - the token at which the error occurs. - // production - the production in which this error occurrs. + // production - the production in which this error occurs. virtual void handleParseError(Token *last, Token *unexpected, JAVACC_SIMPLE_STRING production, VhdlParser *parser) { error_count++; fprintf(stderr, "Encountered: %s at: %d:%d while parsing: %s\n", addUnicodeEscapes(unexpected->image).c_str(), unexpected->beginLine, unexpected->beginColumn, production.c_str()); diff --git a/vhdlparser/ParseException.cc b/vhdlparser/ParseException.cc index 31ee7a3..99649af 100644 --- a/vhdlparser/ParseException.cc +++ b/vhdlparser/ParseException.cc @@ -53,7 +53,7 @@ namespace parser { /** * This is the last token that has been consumed successfully. If * this object has been created due to a parse error, the token - * followng this token will (therefore) be the first error token. + * following this token will (therefore) be the first error token. */ Token currentToken; diff --git a/vhdlparser/ParseException.h b/vhdlparser/ParseException.h index 1f3a3dc..b025912 100644 --- a/vhdlparser/ParseException.h +++ b/vhdlparser/ParseException.h @@ -50,7 +50,7 @@ class ParseException { /** * This is the last token that has been consumed successfully. If * this object has been created due to a parse error, the token - * followng this token will (therefore) be the first error token. + * following this token will (therefore) be the first error token. */ Token currentToken; -- cgit v0.12 From 2e570d3762a412f87fff19ea4a30d60b171a6ea4 Mon Sep 17 00:00:00 2001 From: albert-github Date: Thu, 26 Apr 2018 14:17:16 +0200 Subject: Fortran code coloring improvements (REAL and comment lines) REAL can have multiple meanings in Fortran: - data type - name of (conversion) function in case of free formatted code the word "real" cab appear at the beginning of a (physical) line and would be interpreted incorrectly. Fortran comment lines always end at the end of the line (no block comments) so the code coloring of comment lines should always be terminated. --- src/fortrancode.l | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/fortrancode.l b/src/fortrancode.l index f491acb..ef2b9cf 100644 --- a/src/fortrancode.l +++ b/src/fortrancode.l @@ -931,9 +931,17 @@ PREFIX ((NON_)?RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,4}((NON endFontClass(); } /*-------- variable declaration ----------------------------------*/ +^{BS}"real"/[,:( ] { // real is a bit tricky as it is a data type but also a function. + yy_push_state(YY_START); + BEGIN(Declaration); + startFontClass("keywordtype"); + g_code->codify(yytext); + endFontClass(); + } {TYPE_SPEC}/[,:( ] { QCString typ = yytext; - typ = typ.lower(); + typ = removeRedundantWhiteSpace(typ.lower()); + if (QString(typ).startsWith("real")) YY_FTN_REJECT; if (typ == "type" || typ == "class" || typ == "procedure") inTypeDecl = 1; yy_push_state(YY_START); BEGIN(Declaration); @@ -1188,14 +1196,16 @@ PREFIX ((NON_)?RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,4}((NON /*-----------------------------------------------------------------------------*/ <*>\n { - if (g_endComment) - { - g_endComment=FALSE; - } - else - { - codifyLines(yytext); - } + if (g_endComment) + { + g_endComment=FALSE; + } + else + { + codifyLines(yytext); + // comment cannot extend over the end of a line so should always be terminatd at the end of the line. + if (g_currentFontClass && !strcmp(g_currentFontClass,"comment")) endFontClass(); + } g_contLineNr++; YY_FTN_RESET } -- cgit v0.12 From 39118ed6cef251d1dbdca98801960eab49154128 Mon Sep 17 00:00:00 2001 From: albert-github Date: Thu, 26 Apr 2018 14:22:35 +0200 Subject: Wrong determination of begin / end tag of formula in markdown. The begin tag for a formula during markdown checking was not determined correctly and thus the end tag was not set and the formula code was interpreted which should not be the case (especially in case of labels with '_' in it were miss interpreted . --- src/markdown.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/markdown.cpp b/src/markdown.cpp index de5805f..f7526dc 100644 --- a/src/markdown.cpp +++ b/src/markdown.cpp @@ -240,7 +240,7 @@ static QCString isBlockCommand(const char *data,int offset,int size) { return "f]"; } - else if (data[end]=='}') + else if (data[end]=='{') { return "f}"; } -- cgit v0.12 From 49079853fc4670c11b46e12eba7cb519608be8b0 Mon Sep 17 00:00:00 2001 From: albert-github Date: Thu, 26 Apr 2018 15:15:23 +0200 Subject: Large CALL / CALLER graphs cannot be processed in LaTeX When generating CAL or CALLER graphs thy can become quite large (and unreadable) and it won't be possible to process them into a PDF due to a limitation of TeX. When it is determined that the resulting image is to large a scale down is done to around 150" (still unreadable) but it can be processed, this scaling done is done by means of the `dot` program. (Note: the scaling to 550 points for the output occurs on the original image in the TeX processing and Tex cannot read the image). --- src/dot.cpp | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------- src/dot.h | 28 ++++++++++++++---- 2 files changed, 109 insertions(+), 17 deletions(-) diff --git a/src/dot.cpp b/src/dot.cpp index 80703b9..eeb8b8b 100644 --- a/src/dot.cpp +++ b/src/dot.cpp @@ -266,6 +266,7 @@ static void writeGraphHeader(FTextStream &t,const QCString &title=QCString()) { t << " // INTERACTIVE_SVG=YES\n"; } + t << " // LATEX_PDF_SIZE\n"; // write placeholder for LaTeX PDF bounding box size repacement if (Config_getBool(DOT_TRANSPARENT)) { t << " bgcolor=\"transparent\";" << endl; @@ -437,6 +438,55 @@ static void unsetDotFontPath() g_dotFontPath=""; } +static bool resetPDFSize(const int width,const int height, const char *base) +{ + QString tmpName = QString::fromUtf8(QCString(base)+".tmp"); + QString patchFile = QString::fromUtf8(QCString(base)+".dot"); + if (!QDir::current().rename(patchFile,tmpName)) + { + err("Failed to rename file %s to %s!\n",patchFile.data(),tmpName.data()); + return FALSE; + } + QFile fi(tmpName); + QFile fo(patchFile); + if (!fi.open(IO_ReadOnly)) + { + err("problem opening file %s for patching!\n",tmpName.data()); + QDir::current().rename(tmpName,patchFile); + return FALSE; + } + if (!fo.open(IO_WriteOnly)) + { + err("problem opening file %s for patching!\n",patchFile.data()); + QDir::current().rename(tmpName,patchFile); + fi.close(); + return FALSE; + } + FTextStream t(&fo); + const int maxLineLen=100*1024; + while (!fi.atEnd()) // foreach line + { + QCString line(maxLineLen); + int numBytes = fi.readLine(line.rawData(),maxLineLen); + if (numBytes<=0) + { + break; + } + line.resize(numBytes+1); + if (line.find("LATEX_PDF_SIZE") != -1) + { + double scale = (width > height ? width : height)/double(MAX_LATEX_GRAPH_INCH); + t << " size=\""< li(m_jobs); @@ -792,9 +843,26 @@ bool DotRunner::run() dotArgs+=' '; dotArgs+=s->data(); } - if ((exitCode=portable_system(m_dotExe.data(),dotArgs,FALSE))!=0) + if ((exitCode=portable_system(m_dotExe.data(),dotArgs,FALSE))!=0) goto error; + dotArgs=QCString("\"")+m_file.data()+"\""; + bool redo = FALSE; + for (li.toFirst();(s=li.current());++li) + { + if (s->pdfData()) + { + if (!readBoundingBox(QCString(s->pdfData())+".pdf",&width,&height,FALSE)) goto error; + if ((width > MAX_LATEX_GRAPH_SIZE) || (height > MAX_LATEX_GRAPH_SIZE)) + { + if (!resetPDFSize(width,height,s->pdfData())) goto error; + dotArgs+=' '; + dotArgs+=s->data(); + redo = TRUE; + } + } + } + if (redo) { - goto error; + if ((exitCode=portable_system(m_dotExe.data(),dotArgs,FALSE))!=0) goto error; } } else @@ -802,9 +870,15 @@ bool DotRunner::run() for (li.toFirst();(s=li.current());++li) { dotArgs=QCString("\"")+m_file.data()+"\" "+s->data(); - if ((exitCode=portable_system(m_dotExe.data(),dotArgs,FALSE))!=0) + if ((exitCode=portable_system(m_dotExe.data(),dotArgs,FALSE))!=0) goto error; + if (s->pdfData()) { - goto error; + if (!readBoundingBox(QCString(s->pdfData())+".pdf",&width,&height,FALSE)) goto error; + if ((width > MAX_LATEX_GRAPH_SIZE) || (height > MAX_LATEX_GRAPH_SIZE)) + { + if (!resetPDFSize(width,height,s->pdfData())) goto error; + if ((exitCode=portable_system(m_dotExe.data(),dotArgs,FALSE))!=0) goto error; + } } } } @@ -3150,7 +3224,7 @@ QCString DotClassGraph::writeGraph(FTextStream &out, DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),FALSE); if (usePDFLatex) { - dotRun->addJob("pdf",absPdfName); + dotRun->addJob("pdf",absPdfName,absBaseName); } else { @@ -3508,7 +3582,7 @@ QCString DotInclDepGraph::writeGraph(FTextStream &out, DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),FALSE); if (usePDFLatex) { - dotRun->addJob("pdf",absPdfName); + dotRun->addJob("pdf",absPdfName,absBaseName); } else { @@ -3826,7 +3900,7 @@ QCString DotCallGraph::writeGraph(FTextStream &out, GraphOutputFormat graphForma DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),FALSE); if (usePDFLatex) { - dotRun->addJob("pdf",absPdfName); + dotRun->addJob("pdf",absPdfName,absBaseName); } else { @@ -3992,7 +4066,7 @@ QCString DotDirDeps::writeGraph(FTextStream &out, DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),FALSE); if (usePDFLatex) { - dotRun->addJob("pdf",absPdfName); + dotRun->addJob("pdf",absPdfName,absBaseName); } else { @@ -4170,7 +4244,7 @@ void writeDotGraphFromFile(const char *inFile,const char *outDir, { if (Config_getBool(USE_PDFLATEX)) { - dotRun.addJob("pdf",absOutFile+".pdf"); + dotRun.addJob("pdf",absOutFile+".pdf",absOutFile); } else { @@ -4555,7 +4629,7 @@ QCString DotGroupCollaboration::writeGraph( FTextStream &t, DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),FALSE); if (usePDFLatex) { - dotRun->addJob("pdf",absPdfName); + dotRun->addJob("pdf",absPdfName,absBaseName); } else { diff --git a/src/dot.h b/src/dot.h index dce1a3a..ab6a316 100644 --- a/src/dot.h +++ b/src/dot.h @@ -42,6 +42,12 @@ class DotRunnerQueue; enum GraphOutputFormat { GOF_BITMAP, GOF_EPS }; enum EmbeddedOutputFormat { EOF_Html, EOF_LaTeX, EOF_Rtf, EOF_DocBook }; +// the graphicx LaTeX has a limitation of maximum size of 16384 +// To be on the save side we take it a little bit smaller i.e. 150 inch * 72 dpi +// It is anyway hard to view these size of images +#define MAX_LATEX_GRAPH_INCH 150 +#define MAX_LATEX_GRAPH_SIZE (MAX_LATEX_GRAPH_INCH * 72) + /** Attributes of an edge of a dot graph */ struct EdgeInfo { @@ -338,11 +344,12 @@ class DotGroupCollaboration class DotConstString { public: - DotConstString() { m_str=0; } - ~DotConstString() { delete[] m_str; } - DotConstString(const QCString &s) : m_str(0) { set(s); } - DotConstString(const DotConstString &s) : m_str(0) { set(s.data()); } + DotConstString() { m_str=0; m_pdfstr=0;} + ~DotConstString() { delete[] m_str; delete[] m_pdfstr;} + DotConstString(const QCString &s, const QCString &p = NULL) : m_str(0), m_pdfstr(0) { set(s); setpdf(p);} + DotConstString(const DotConstString &s) : m_str(0), m_pdfstr(0) { set(s.data()); } const char *data() const { return m_str; } + const char *pdfData() const { return m_pdfstr; } bool isEmpty() const { return m_str==0 || m_str[0]=='\0'; } void set(const QCString &s) { @@ -354,9 +361,20 @@ class DotConstString qstrcpy(m_str,s.data()); } } + void setpdf(const QCString &p) + { + delete[] m_pdfstr; + m_pdfstr=0; + if (!p.isEmpty()) + { + m_pdfstr=new char[p.length()+1]; + qstrcpy(m_pdfstr,p.data()); + } + } private: DotConstString &operator=(const DotConstString &); char *m_str; + char *m_pdfstr; }; /** Helper class to run dot from doxygen. @@ -377,7 +395,7 @@ class DotRunner /** Adds an additional job to the run. * Performing multiple jobs one file can be faster. */ - void addJob(const char *format,const char *output); + void addJob(const char *format,const char *output, const char *base = NULL); void addPostProcessing(const char *cmd,const char *args); -- cgit v0.12 From ee1ea269e1c684cf5ff39ed836fd8af288837275 Mon Sep 17 00:00:00 2001 From: albert-github Date: Thu, 26 Apr 2018 15:56:25 +0200 Subject: Bug 768240 - Make maxLineLen of latex output configurable Removing the automatic line breaking after 108 characters (also didn't work properly with e.g. executive paper size). Due to new implementation some character encodings had to be changed as well as well as handling of the single quote in formulas. --- src/latexdocvisitor.cpp | 16 +++++++- src/latexgen.cpp | 96 ++++++++++++++++++++++++++++++++------------- templates/latex/doxygen.sty | 62 +++++++++++++++++++++++------ 3 files changed, 133 insertions(+), 41 deletions(-) diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp index 5a67c15..86ceade 100644 --- a/src/latexdocvisitor.cpp +++ b/src/latexdocvisitor.cpp @@ -526,7 +526,19 @@ void LatexDocVisitor::visit(DocIncOperator *op) void LatexDocVisitor::visit(DocFormula *f) { if (m_hide) return; - m_t << f->text(); + const char *p=f->text(); + char c; + if (p) + { + while ((c=*p++)) + { + switch (c) + { + case '\'': m_t << "\\text{'}"; break; + default: m_t << c; break; + } + } + } } void LatexDocVisitor::visit(DocIndexEntry *i) @@ -927,7 +939,7 @@ static void writeStartTableCommand(FTextStream &t,const DocNode *n,int cols) } else { - t << "\\tabulinesep=1mm\n\\begin{longtabu} spread 0pt [c]{*{" << cols << "}{|X[-1]}|}\n"; + t << "\\tabulinesep=1mm\n\\begin{longtabu}spread 0pt [c]{*{" << cols << "}{|X[-1]}|}\n"; } //return isNested ? "TabularNC" : "TabularC"; } diff --git a/src/latexgen.cpp b/src/latexgen.cpp index 9b07fe6..7d72974 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -38,6 +38,7 @@ #include "filename.h" #include "resourcemgr.h" +static bool DoxyCodeOpen = FALSE; //------------------------------- LatexCodeGenerator::LatexCodeGenerator(FTextStream &t,const QCString &relPath,const QCString &sourceFileName) @@ -77,8 +78,8 @@ void LatexCodeGenerator::codify(const char *str) //char cs[5]; int spacesToNextTabStop; static int tabSize = Config_getInt(TAB_SIZE); - const int maxLineLen = 108; - QCString result(4*maxLineLen+1); // worst case for 1 line of 4-byte chars + static char *result = NULL; + static int lresult = 0; int i; while ((c=*p)) { @@ -86,9 +87,17 @@ void LatexCodeGenerator::codify(const char *str) { case 0x0c: p++; // remove ^L break; + case ' ': m_t <<" "; + m_col++; + p++; + break; + case '^': m_t <<"\\string^"; + m_col++; + p++; + break; case '\t': spacesToNextTabStop = tabSize - (m_col%tabSize); - m_t << Doxygen::spaces.left(spacesToNextTabStop); + for (i = 0; i < spacesToNextTabStop; i++) m_t <<" "; m_col+=spacesToNextTabStop; p++; break; @@ -100,6 +109,11 @@ void LatexCodeGenerator::codify(const char *str) #undef COPYCHAR // helper macro to copy a single utf8 character, dealing with multibyte chars. #define COPYCHAR() do { \ + if (lresult < (i + 5)) \ + { \ + lresult += 512; \ + result = (char *)realloc(result, lresult); \ + } \ result[i++]=c; p++; \ if (c<0) /* multibyte utf-8 character */ \ { \ @@ -116,30 +130,16 @@ void LatexCodeGenerator::codify(const char *str) result[i++]=*p++; \ } \ } \ - m_col++; \ + m_col++; \ } while(0) - // gather characters until we find whitespace or are at - // the end of a line + // gather characters until we find whitespace or another special character COPYCHAR(); - if (m_col>=maxLineLen) // force line break - { - m_t << "\n "; - m_col=0; - } - else // copy more characters + while ((c=*p) && + c!=0x0c && c!='\t' && c!='\n' && c!=' ' && c!='^' + ) { - while (m_col=maxLineLen) // force line break - { - m_t << "\n "; - m_col=0; - } + COPYCHAR(); } result[i]=0; // add terminator //if (m_prettyCode) @@ -190,6 +190,11 @@ void LatexCodeGenerator::writeLineNumber(const char *ref,const char *fileName,co { static bool usePDFLatex = Config_getBool(USE_PDFLATEX); static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS); + if (!DoxyCodeOpen) + { + m_t << "\\DoxyCodeLine{"; + DoxyCodeOpen = TRUE; + } if (m_prettyCode) { QCString lineNumber; @@ -223,10 +228,20 @@ void LatexCodeGenerator::writeLineNumber(const char *ref,const char *fileName,co void LatexCodeGenerator::startCodeLine(bool) { m_col=0; + if (!DoxyCodeOpen) + { + m_t << "\\DoxyCodeLine{"; + DoxyCodeOpen = TRUE; + } } void LatexCodeGenerator::endCodeLine() { + if (DoxyCodeOpen) + { + m_t << "}"; + DoxyCodeOpen = FALSE; + } codify("\n"); } @@ -472,8 +487,7 @@ static void writeDefaultHeaderPart1(FTextStream &t) t << "% Packages required by doxygen\n" "\\usepackage{fixltx2e}\n" // for \textsubscript "\\usepackage{calc}\n" - "\\usepackage{doxygen}\n" - "\\usepackage[export]{adjustbox} % also loads graphicx\n"; + "\\usepackage{doxygen}\n"; QStrList extraLatexStyle = Config_getList(LATEX_EXTRA_STYLESHEET); for (uint i=0; i