From 1a5bbadb43b2d30e338d26a0d495b60e2b12f704 Mon Sep 17 00:00:00 2001 From: albert-github Date: Wed, 11 Dec 2019 20:14:29 +0100 Subject: issue #7436 Incorrect handling of block comments in VHDL The search for `/*` or /*!` ended at the last `*/` in a file and thus skipping other intermediate block end and new starts. Also the intermediate code was lost see as comment. The filter pattern used was incorrect and should have been `<"/*" (~["*"])* "*" ("*" | ~["*","/"] (~["*"])* "*")* "/">` (thanks to https://javacc.org/contrib/C.jj). Here also the space plus one or more `*` at the end beginning of the line are still incorporated as well as multiple `*` before the colosing `*/` this is also filtered. --- src/growbuf.h | 1 + src/vhdljjparser.cpp | 35 ++++++++++++++++++++++++++++++++++- src/vhdljjparser.h | 2 +- vhdlparser/vhdlparser.jj | 12 ++++++------ 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/growbuf.h b/src/growbuf.h index 4c49dce..bf6d74e 100644 --- a/src/growbuf.h +++ b/src/growbuf.h @@ -47,6 +47,7 @@ class GrowBuf } const char *get() { return str; } int getPos() const { return pos; } + void setPos(const int newPos) { pos = newPos; } char at(int i) const { return str[i]; } private: char *str; diff --git a/src/vhdljjparser.cpp b/src/vhdljjparser.cpp index 8b7ebf6..4848a3e 100644 --- a/src/vhdljjparser.cpp +++ b/src/vhdljjparser.cpp @@ -29,6 +29,7 @@ #include "arguments.h" #include "types.h" #include "VhdlParserIF.h" +#include "growbuf.h" using namespace vhdl::parser; using namespace std; @@ -169,7 +170,7 @@ void VhdlParser::lineCount(const char* text) { for (const char* c=text ; *c ; ++c ) { - yyLineNr += (*c == '\n') ; + if (*c == '\n') yyLineNr++; } } @@ -744,3 +745,35 @@ const char *getVhdlFileName(void) { return vhdlFileName; } + +QCString filter2008VhdlComment(const char *s) +{ + GrowBuf growBuf; + const char *p=s+3; // skip /*! + char c,pc='\0'; + while (*p == ' ' || *p == '\t') p++; + while ((c=*p++)) + { + growBuf.addChar(c); + if (c == '\n') + { + // special handling of space followed by * at beginning of line + while (*p == ' ' || *p == '\t') p++; + while (*p == '*') p++; + // special attention in case character at end is / + if (*p == '/') p++; + } + } + // special attention in case */ at end of last line + int len = growBuf.getPos(); + if (growBuf.at(len-1) == '/' && growBuf.at(len-2) == '*') + { + len -= 2; + while (growBuf.at(len-1) == '*') len--; + c = growBuf.at(len-1); + while ((c = growBuf.at(len-1)) == ' ' || c == '\t') len--; + growBuf.setPos(len); + } + growBuf.addChar(0); + return growBuf.get(); +} diff --git a/src/vhdljjparser.h b/src/vhdljjparser.h index 53eb0be..f6cd17d 100644 --- a/src/vhdljjparser.h +++ b/src/vhdljjparser.h @@ -83,5 +83,5 @@ void vhdlscanFreeScanner(); const QList& getVhdlConfiguration(); const std::vector >&getVhdlInstList(); - +QCString filter2008VhdlComment(const char *s); #endif diff --git a/vhdlparser/vhdlparser.jj b/vhdlparser/vhdlparser.jj index 8a76bc6..3151528 100644 --- a/vhdlparser/vhdlparser.jj +++ b/vhdlparser/vhdlparser.jj @@ -107,17 +107,17 @@ SKIP: // VHDL 2008 doxygen comment /*! .... */ SKIP : { - + { { - QCString q(image.data()); - q.stripPrefix("/*!"); - q.resize(q.length()-2); + QCString q = filter2008VhdlComment(image.data()); ::vhdl::parser::VhdlParser::handleCommentBlock(q.data(),TRUE);image.clear(); } } - | {::vhdl::parser::VhdlParser::lineCount(image.data());image.clear();} -} + | + { + ::vhdl::parser::VhdlParser::lineCount(image.data());image.clear();} + } /* KEYWORDS */ -- cgit v0.12