Commit 85c46d2a authored by mk's avatar mk

some changes

parent ed39dab5
......@@ -48,6 +48,6 @@ distclean: clean
ce_parse.cpp ce_parse.h tag.cpp commentscan.cpp \
declinfo.cpp defargs.cpp commentcnv.cpp doctokenizer.cpp \
pycode.cpp pyscanner.cpp fortrancode.cpp fortranscanner.cpp \
vhdlscanner.cpp vhdlcode.cpp tclscanner.cpp
vhdlscanner.cpp vhdlcode.cpp tclscanner.cpp verilogscanner.cpp VPreLex.cpp
FORCE:
%option noyywrap align interactive
%option stack
%option noc++
%option prefix="VPreLex"
%{
/******************************************************************************
* DESCRIPTION: Verilog Preprocessor Lexer
*
* This file is part of Verilog-Perl.
*
* Author: Wilson Snyder <wsnyder@wsnyder.org>
*
* Code available from: http://www.veripool.org/systemperl
*
******************************************************************************
*
* Copyright 2000-2013 by Wilson Snyder. This program is free software;
* you can redistribute it and/or modify it under the terms of either the GNU
* Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*****************************************************************************
* Do not use Flex in C++ mode. It has bugs with yyunput() which result in
* lost characters.
*****************************************************************************/
#include "VPreProc.h"
#include "VPreLex.h"
#include <cstdio>
#include <cstdarg>
#include <cstring>
#include <iostream>
#include "qcstring.h"
#include "define.h"
// Flex 2.5.35 has compile warning in ECHO, so we'll default our own rule
#define ECHO yyerror_f("Missing VPreLex.l rule: ECHO rule invoked in state %d: %s", YY_START, yytext);
struct VPreProcImp;
VPreLex* VPreLex::s_currentLexp = NULL; // Current lexing point
#define LEXP VPreLex::s_currentLexp
#define linenoInc() { LEXP->linenoInc(); }
static bool pedantic() { return LEXP->m_pedantic; }
static bool keepWhitespace() { return LEXP->m_keepWhitespace; }
static void appendDefValue(const char* t, size_t l) { LEXP->appendDefValue(t,l); }
void yyerrorx(char* msg) { LEXP->curFilelinep()->error(msg); }
#define YY_INPUT(buf,result,max_size) \
result = LEXP->inputToLex(buf,max_size);
// Accessors, because flex keeps changing the type of yyleng
char* yyourtext() { return yytext; }
size_t yyourleng() { return (size_t)yyleng; }
void yyourtext(const char* textp, size_t size) { yytext=(char*)textp; yyleng=size; }
void yyerror_f(const char* format, ...) {
char msg[1024];
va_list ap;
va_start(ap,format);
vsprintf(msg,format,ap);
va_end(ap);
yyerrorx(msg);
}
typedef size_t ussize_t;
/**********************************************************************/
%}
%x CMTMODE
%x STRMODE
%x DEFFPAR
%x DEFFORM
%x DEFVAL
%x DEFCMT
%x ARGMODE
%x INCMODE
%x PRTMODE
%x OFFMODE
/* drop: Drop Ctrl-Z - can't pass thru or may EOF the output too soon */
ws [ \t\f\r]
wsn [ \t\f]
crnl [\r]*[\n]
quote [\"]
tickquote [`][\"]
/* Where we use symb/symbdef, we must also look for a `` join */
/* Note in the preprocessor \ESCaped is *not* always special; mantis1537/bug441 */
backslash [\\]
symb ([a-zA-Z_][a-zA-Z0-9_$]*|\\[^ \t\f\r\n]+)
symbdef ([a-zA-Z_][a-zA-Z0-9_$]*|\\[^ \t\f\r\n`]+)
word [a-zA-Z0-9_]+
drop [\032]
/* Case insensitive; unfortunately ?i: isn't in flex 2.5.4 which is popular */
ambit [Aa][Mm][Bb][Ii][Tt]
pragma [Pp][Rr][Aa][Gg][Mm][Aa]
synopsys [Ss][Yy][Nn][Oo][Pp][Ss][Yy][Ss]
synthesis [Ss][Yy][Nn][Tt][Hh][Ee][Ss][Ii][Ss]
pragma_tools ({ambit}|{pragma}|{synopsys}|{synthesis})
translate_off [Tt][Rr][Aa][Nn][Ss][Ll][Aa][Tt][Ee]_[Oo][Ff][Ff]
translate_on [Tt][Rr][Aa][Nn][Ss][Ll][Aa][Tt][Ee]_[Oo][Nn]
prag_trans_off ({ws}*{pragma_tools}{ws}+{translate_off}{ws}*)
prag_trans_on ({ws}*{pragma_tools}{ws}+{translate_on}{ws}*)
/**************************************************************/
%%
<INITIAL>^{ws}*"`line"{ws}+.*{crnl} { LEXP->lineDirective(yytext);
return(VP_LINE); }
/* Special directives we recognize */
<INITIAL>"`define" { return(VP_DEFINE); }
<INITIAL>"`else" { return(VP_ELSE); }
<INITIAL>"`elsif" { return(VP_ELSIF); }
<INITIAL>"`endif" { return(VP_ENDIF); }
<INITIAL>"`ifdef" { return(VP_IFDEF); }
<INITIAL>"`ifndef" { return(VP_IFNDEF); }
<INITIAL>"`include" { return(VP_INCLUDE); }
<INITIAL>"`undef" { return(VP_UNDEF); }
<INITIAL>"`undefineall" { return(VP_UNDEFINEALL); }
/* Optional directives we recognize */
<INITIAL>"`__FILE__" { static string rtnfile;
rtnfile = '"'; rtnfile += LEXP->curFilelinep()->filename();
rtnfile += '"'; yytext=(char*)rtnfile.c_str(); yyleng = rtnfile.length();
return (VP_STRING); }
<INITIAL>"`__LINE__" { static char buf[10];
sprintf(buf, "%d",LEXP->curFilelinep()->lineno());
yytext = buf; yyleng = strlen(yytext);
return (VP_TEXT); }
<INITIAL>"`error" { if (!pedantic()) return (VP_ERROR); else return(VP_DEFREF); }
/* Pass-through strings */
<INITIAL>{quote} { yy_push_state(STRMODE); yymore(); }
<STRMODE><<EOF>> { linenoInc(); yyerror_f("EOF in unterminated string"); yyleng=0; yyterminate(); }
<STRMODE>{crnl} { linenoInc(); yyerror_f("Unterminated string"); BEGIN(INITIAL); }
<STRMODE>{word} { yymore(); }
<STRMODE>[^\"\\] { yymore(); }
<STRMODE>{backslash}{crnl} { linenoInc(); yymore(); }
<STRMODE>{backslash}. { yymore(); }
<STRMODE>{quote} { yy_pop_state();
if (LEXP->m_parenLevel || LEXP->m_formalLevel) { appendDefValue(yytext,yyleng); yyleng=0; }
else return (VP_STRING); }
/* Stringification */
<INITIAL>{tickquote} { return VP_STRIFY; }
<INITIAL>"`\\`\"" { return VP_BACKQUOTE; }
/* Protected blocks */
<INITIAL>"`protected" { yy_push_state(PRTMODE); yymore(); }
<PRTMODE><<EOF>> { linenoInc(); yyerror_f("EOF in `protected"); yyleng=0; yyterminate(); }
<PRTMODE>{crnl} { linenoInc(); yymore(); }
<PRTMODE>. { yymore(); }
<PRTMODE>"`endprotected" { yy_pop_state(); return (VP_TEXT); }
/* Pass-through include <> filenames */
<INCMODE><<EOF>> { linenoInc(); yyerror_f("EOF in unterminated include filename"); yyleng=0; yyterminate(); }
<INCMODE>{crnl} { linenoInc(); yyerror_f("Unterminated include filename"); BEGIN(INITIAL); }
<INCMODE>[^\>\\] { yymore(); }
<INCMODE>{backslash}. { yymore(); }
<INCMODE>[\>] { yy_pop_state(); return (VP_STRING); }
/* Reading definition formal parenthesis (or not) to begin formal arguments */
/* Note '(' must IMMEDIATELY follow definition name */
<DEFFPAR>[(] { appendDefValue("(",1); LEXP->m_formalLevel=1; BEGIN(DEFFORM); }
<DEFFPAR>{crnl} { yy_pop_state(); yytext=(char*)"\n"; unput('\n'); yyleng=1; return VP_DEFFORM; } /* DEFVAL will later grab the return */
<DEFFPAR><<EOF>> { yy_pop_state(); return VP_DEFFORM; } /* empty formals */
<DEFFPAR>. {
QCString s=yytext;
yy_pop_state(); unput(yytext[yyleng-1]); yyleng=0; return VP_DEFFORM;
} /* empty formals */
/* Reading definition formals (declaration of a define) */
<DEFFORM>[(] { appendDefValue(yytext,yyleng); yyleng=0; ++LEXP->m_formalLevel; }
<DEFFORM>[)] { appendDefValue(yytext,yyleng); yyleng=0; if ((--LEXP->m_formalLevel)==0) { yy_pop_state(); return VP_DEFFORM; } }
<DEFFORM>"/*" { yy_push_state(CMTMODE); yymore(); }
<DEFFORM>"//"[^\n\r]* { return (VP_COMMENT);}
<DEFFORM>{drop} { }
<DEFFORM><<EOF>> { linenoInc(); yy_pop_state(); yyerror_f("Unterminated ( in define formal arguments."); yyleng=0; return VP_DEFFORM; }
<DEFFORM>{crnl} { linenoInc(); appendDefValue((char*)"\n",1); } /* Include return so can maintain output line count */
<DEFFORM>[\\]{crnl} { linenoInc(); appendDefValue((char*)"\\\n",2); } /* Include return so can maintain output line count */
<DEFFORM>{quote} { yy_push_state(STRMODE); yymore(); } /* Legal only in default values */
<DEFFORM>"`\\`\"" { appendDefValue(yytext,yyleng); } /* Maybe illegal, otherwise in default value */
<DEFFORM>{tickquote} { appendDefValue(yytext,yyleng); } /* Maybe illegal, otherwise in default value */
<DEFFORM>[{\[] { LEXP->m_formalLevel++; appendDefValue(yytext,yyleng); }
<DEFFORM>[}\]] { LEXP->m_formalLevel--; appendDefValue(yytext,yyleng); }
<DEFFORM>[^\/\*\n\r\\(){}\[\]\"]+ |
<DEFFORM>[\\][^\n\r] |
<DEFFORM>. { appendDefValue(yytext,yyleng); }
/* Reading definition value (declaration of a define's text) */
<DEFVAL>"/*" { LEXP->m_defCmtSlash=false; yy_push_state(DEFCMT); yymore(); } /* Special comment parser */
<DEFVAL>"//"[^\n\r]*[\\]{crnl} { linenoInc(); appendDefValue((char*)"\n",1); } /* Spec says // not part of define value */
<DEFVAL>"//"[^\n\r]* { return (VP_COMMENT);}
<DEFVAL>{drop} { }
<DEFVAL><<EOF>> { linenoInc(); yy_pop_state(); yytext=(char*)"\n"; yyleng=1; return (VP_DEFVALUE); } /* Technically illegal, but people complained */
<DEFVAL>{crnl} { linenoInc(); yy_pop_state(); yytext=(char*)"\n"; yyleng=1; return (VP_DEFVALUE); }
<DEFVAL>[\\]{crnl} { linenoInc(); appendDefValue((char*)"\\\n",2); } /* Return, AND \ is part of define value */
<DEFVAL>[^\/\*\n\r\\]+ |
<DEFVAL>[\\][^\n\r] |
<DEFVAL>. {
QCString s=yytext;
appendDefValue(yytext,yyleng);
}
/* Comments inside define values - if embedded get added to define value per spec */
/* - if no \{crnl} ending then the comment belongs to the next line, as a non-embedded comment */
/* - if all but (say) 3rd line is missing \ then it's indeterminate */
<DEFCMT>"*/" { yy_pop_state(); appendDefValue(yytext,yyleng); }
<DEFCMT>[\\]{crnl} { linenoInc(); LEXP->m_defCmtSlash=true;
appendDefValue(yytext,yyleng-2); appendDefValue((char*)"\n",1); } /* Return but not \ */
<DEFCMT>{crnl} { linenoInc(); yymore(); if (LEXP->m_defCmtSlash) yyerror_f("One line of /* ... */ is missing \\ before newline");
BEGIN(CMTMODE); }
<DEFCMT>{word} { yymore(); }
<DEFCMT>. { yymore(); }
<DEFCMT><<EOF>> { yyerror_f("EOF in '/* ... */' block comment\n"); yyleng=0; yyterminate(); }
/* Define arguments (use of a define) */
<ARGMODE>"/*" { yy_push_state(CMTMODE); yymore(); }
<ARGMODE>"//"[^\n\r]* { return (VP_COMMENT);}
<ARGMODE>{drop} { }
<ARGMODE><<EOF>> { yyerror_f("EOF in define argument list\n"); yyleng = 0; yyterminate(); }
<ARGMODE>{crnl} { linenoInc(); yytext=(char*)"\n"; yyleng=1; return(VP_WHITE); }
<ARGMODE>{quote} { yy_push_state(STRMODE); yymore(); }
<ARGMODE>"`\\`\"" { appendDefValue(yytext,yyleng); } /* Literal text */
<ARGMODE>{tickquote} { return(VP_STRIFY); }
<ARGMODE>[{\[] { LEXP->m_parenLevel++; appendDefValue(yytext,yyleng); }
<ARGMODE>[}\]] { LEXP->m_parenLevel--; appendDefValue(yytext,yyleng); }
<ARGMODE>[(] { LEXP->m_parenLevel++;
// Note paren level 0 means before "(" of starting args
// Level 1 means "," between arguments
// Level 2+ means one argument's internal ()
if (LEXP->m_parenLevel>1) {
appendDefValue(yytext,yyleng);
} else {
return (VP_TEXT);
}}
<ARGMODE>[)] { LEXP->m_parenLevel--;
if (LEXP->m_parenLevel>0) {
appendDefValue(yytext,yyleng);
} else {
yy_pop_state(); return (VP_DEFARG);
}}
<ARGMODE>[,] { if (LEXP->m_parenLevel>1) {
appendDefValue(yytext,yyleng);
} else {
yy_pop_state(); return (VP_DEFARG);
}}
<ARGMODE>"`"{symbdef} { appendDefValue(yytext,yyleng); } /* defref in defref - outer macro expands first */
<ARGMODE>"`"{symbdef}`` { appendDefValue(yytext,yyleng); } /* defref in defref - outer macro expands first */
<ARGMODE>[^\/\*\n\r\\(,){}\[\]\"`]+ |
<ARGMODE>. { appendDefValue(yytext,yyleng); }
/* Translate offs. Note final newline not included */
<INITIAL>(("//"{prag_trans_off}[^\n\r]*)|("/*"{prag_trans_off}"*/")) {
if (LEXP->m_synthesis) { yy_push_state(OFFMODE); }
return(VP_COMMENT); }
<OFFMODE>(("//"{prag_trans_on}[^\n\r]*)|("/*"{prag_trans_on}"*/")) {
if (LEXP->m_synthesis) { yy_pop_state(); }
return(VP_COMMENT); }
<OFFMODE>{crnl} { linenoInc(); yymore(); } /* Need to end the / / */
<OFFMODE>{word} { }
<OFFMODE>. { }
<OFFMODE><<EOF>> { yyerror_f("EOF in '/*synthesis translate_off*/' region\n"); yyleng=0; yyterminate(); }
/* One line comments. Note final newline not included */
<INITIAL>"//"[^\n\r]* { return (VP_COMMENT); }
/* C-style comments. */
/**** See also DEFCMT */
<INITIAL>"/*" { yy_push_state(CMTMODE); yymore(); }
<CMTMODE>"*/" { yy_pop_state(); return(VP_COMMENT); }
<CMTMODE>{crnl} { linenoInc(); yymore(); }
<CMTMODE>{word} { yymore(); }
<CMTMODE>. { yymore(); }
<CMTMODE><<EOF>> { yyerror_f("EOF in '/* ... */' block comment\n"); yyleng=0; yyterminate(); }
/* Define calls */
/* symbdef prevents normal lex rules from making `\`"foo a symbol {`"foo} instead of a BACKQUOTE */
<INITIAL>"`"{symbdef} {
QCString s=yytext;
s.stripPrefix("`");
DefineDict* gDict = VerilogPreProc::getPreDefineDict();
Define *def=gDict->find(s.data());
if(def)
{
yytext=def->args.data();
yyleng=def->args.length();
return VP_TEXT;
}
return (VP_DEFREF);
}
<INITIAL>"`"{symbdef}`` { yyleng-=2; return (VP_DEFREF_JOIN); }
/* Generics */
<INITIAL><<EOF>> { yyterminate(); } /* A "normal" EOF */
<INITIAL>{crnl} { linenoInc(); yytext=(char*)"\n"; yyleng=1; return(VP_WHITE); }
<INITIAL>{symb} {
static QCString s;
s.append(yytext);
s.append("#");
// yytext=s.data();
return (VP_SYMBOL);
}
<INITIAL>{symb}`` { yyleng-=2; return (VP_SYMBOL_JOIN); }
<INITIAL>[\r] { }
<INITIAL>{wsn}+ { if (!keepWhitespace()) { yytext=(char*)" "; yyleng=1; } return VP_WHITE; }
<INITIAL>{drop} { }
<INITIAL>. {
return (VP_TEXT);
}
<*>.|\n { yymore(); } /* Prevent hitting ECHO; */
%%
void VPreLex::pushStateDefArg(int level) {
// Enter define substitution argument state
yy_push_state(ARGMODE);
m_parenLevel = level;
m_defValue = "";
}
void VPreLex::pushStateDefForm() {
// Enter define formal arguments state
yy_push_state(DEFFPAR); // First is an optional ( to begin args
m_parenLevel = 0;
m_defValue = "";
}
void VPreLex::pushStateDefValue() {
// Enter define value state
yy_push_state(DEFVAL);
m_parenLevel = 0;
m_defValue = "";
}
void VPreLex::pushStateIncFilename() {
// Enter include <> filename state
yy_push_state(INCMODE);
yymore();
}
void VPreLex::debug(int level) {
//#ifdef FLEX_DEBUG
// yy_flex_debug=0;
//#endif
}
int VPreLex::debug() {
#ifdef FLEX_DEBUG
return yy_flex_debug;
#else
return 0;
#endif
}
int VPreLex::lex() {
VPreLex::s_currentLexp = this; // Tell parser where to get/put data
m_tokFilelinep = curFilelinep(); // Remember token start location, may be updated by the lexer later
return yylex();
}
size_t VPreLex::inputToLex(char* buf, size_t max_size) {
// We need a custom YY_INPUT because we can't use flex buffers.
// Flex buffers are limited to 2GB, and we can't chop into 2G pieces
// because buffers can't end in the middle of tokens.
// Note if we switched streams here (which we don't) "buf" would be
// become a stale invalid pointer.
//
VPreStream* streamp = curStreamp();
if (debug()>=10) { cout<<"- pp:inputToLex ITL s="<<max_size<<" bs="<<streamp->m_buffers.size()<<endl; dumpStack(); }
// For testing, use really small chunks
//if (max_size > 13) max_size=13;
again:
size_t got = 0;
// Get from this stream
while (got < max_size // Haven't got enough
&& !streamp->m_buffers.empty()) { // And something buffered
string front = curStreamp()->m_buffers.front(); streamp->m_buffers.pop_front();
size_t len = front.length();
if (len > (max_size-got)) { // Front string too big
len = (max_size-got);
string remainder = front.substr(len);
front = front.substr(0, len);
streamp->m_buffers.push_front(remainder); // Put back remainder for next time
}
strncpy(buf+got, front.c_str(), len);
got += len;
}
if (!got) { // end of stream; try "above" file
bool again=false;
string forceOut = endOfStream(again/*ref*/);
streamp = curStreamp(); // May have been updated
if (forceOut != "") {
if (forceOut.length() > max_size) {
yyerror_f("Output buffer too small for a `line");
} else {
got = forceOut.length();
strncpy(buf, forceOut.c_str(), got);
}
} else {
if (streamp->m_eof) {
if (debug()) cout<<"- EOF\n";
}
got = 0; // 0=EOF/EOS - although got was already 0.
if (again) goto again;
}
}
// if (true) { cout<<"- pp::inputToLex got="<<got<<" '"<<string(buf,got)<<"'"<<endl; }
return got;
}
string VPreLex::endOfStream(bool& againr) {
// Switch to file or next unputString
// VPreProcImp *iimp = this->m_preimpp;
againr = false;
dumpStack();
if (debug())
{
// cout<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
// cout<<iimp->m_lineChars<<endl;
// cout<<"-EOS state="<<curStreamp()->m_termState<<" at "<<curFilelinep()<<endl;
// cout<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
}
if (curStreamp()->m_eof) return ""; // Don't delete the final "EOF" stream
bool exited_file = curStreamp()->m_file;
if (!exited_file) {
// Midpoint of stream, just change buffers
delete curStreamp();
m_streampStack.pop(); // Must work as size>1; EOF is entry 0
againr = true;
return "";
}
// Multiple steps because we need FLEX to see ending \n and EOS to end
// any illegal states, like an unterminated `protected region
else if (!curStreamp()->m_termState) {
// First shutdown phase for a file
// Terminate all files with a newline. This prevents problems if
// the user had a define without a terminating newline,
// otherwise the resumed file's next line would get tacked on.
// Also makes it likely the `line that changes files comes out
// immediately.
curStreamp()->m_termState = 1;
return "\n"; // Exit old file
}
else if (curStreamp()->m_termState == 1) {
// Now the EOF - can't be sent with other characters
curStreamp()->m_termState = 2;
return ""; // End of file
}
else if (curStreamp()->m_termState == 2) {
// Now ending `line
curStreamp()->m_termState = 3;
return curFilelinep()->lineDirectiveStrg(2); // Exit old file
}
else {
// Final shutdown phase for a stream, we can finally change the
// current fileline to the new stream
curStreamp()->m_termState = 0;
VFileLine* filelinep = curFilelinep();
delete curStreamp();
m_streampStack.pop(); // Must work as size>1; EOF is entry 0
if (curStreamp()->m_eof) {
// EOF doesn't have a "real" fileline, but a linenumber of 0 from init time
// Inherit whatever we last parsed so it's more obvious.
curFilelinep(filelinep);
}
// The caller parser remembered the start location for the text we are parsing,
// but we've discovered there was a file switch along the way, so update it.
m_tokFilelinep = curFilelinep();
//
if (curStreamp()->m_eof) {
return "";
} else {
return curFilelinep()->lineDirectiveStrg(0); // Reenter resumed file
}
}
}
void VPreLex::initFirstBuffer(VFileLine* filelinep) {
// Called from constructor to make first buffer
// yy_create_buffer also sets yy_fill_buffer=1 so reads from YY_INPUT
VPreStream* streamp = new VPreStream(filelinep, this);
streamp->m_eof = true;
m_streampStack.push(streamp);
//
m_bufferState = yy_create_buffer(NULL, YY_BUF_SIZE);
yy_switch_to_buffer(m_bufferState);
yyrestart(NULL);
}
void VPreLex::scanNewFile(VFileLine* filelinep) {
// Called on new open file. scanBytesBack will be called next.
if (streamDepth() > VPreProc::DEFINE_RECURSION_LEVEL_MAX) {
// The recursive `include in VPreProcImp should trigger first
yyerror_f("Recursive `define or other nested inclusion");
curStreamp()->m_eof = true; // Fake it to stop recursion
} else {
VPreStream* streamp = new VPreStream(filelinep, this);
m_tokFilelinep = curFilelinep();
streamp->m_file = true;
scanSwitchStream(streamp);
}
}
void VPreLex::scanBytes(const string& str) {
// Note buffers also appended in ::scanBytesBack
// Not "m_buffers.push_front(string(strp,len))" as we need a `define
// to take effect immediately, in the middle of the current buffer
// Also we don't use scan_bytes that would set yy_fill_buffer
// which would force Flex to bypass our YY_INPUT routine.
if (streamDepth() > VPreProc::DEFINE_RECURSION_LEVEL_MAX) {
// More streams if recursive `define with complex insertion
// More buffers mostly if something internal goes funky
yyerror_f("Recursive `define or other nested inclusion");
curStreamp()->m_eof = true; // Fake it to stop recursion
} else {
VPreStream* streamp = new VPreStream(curFilelinep(), this);
streamp->m_buffers.push_front(str);
scanSwitchStream(streamp);
}
}
void VPreLex::scanSwitchStream(VPreStream* streamp) {
curStreamp()->m_buffers.push_front(currentUnreadChars());
m_streampStack.push(streamp);
yyrestart(NULL);
}
void VPreLex::scanBytesBack(const string& str) {
// Initial creation, that will pull from YY_INPUT==inputToLex
// Note buffers also appended in ::scanBytes
if (curStreamp()->m_eof) yyerror_f("scanBytesBack without being under scanNewFile");
curStreamp()->m_buffers.push_back(str);
}
string VPreLex::currentUnreadChars() {
// WARNING - Peeking at internals
if (!currentBuffer()) return "";
ussize_t left = (yy_n_chars - (yy_c_buf_p - currentBuffer()->yy_ch_buf));
if (left > 0) { // left may be -1 at EOS
*(yy_c_buf_p) = (yy_hold_char);
return string(yy_c_buf_p, left);
} else {
return "";
}
}
YY_BUFFER_STATE VPreLex::currentBuffer() {
return YY_CURRENT_BUFFER;
}
char* VPreLex::getInputBuffer() {
return currentBuffer()->yy_ch_buf;
}
char* VPreLex::getInputBuffer1() {
return m_bufferState->yy_ch_buf;
}
int VPreLex::currentStartState() {
return YY_START;
}
void VPreLex::dumpSummary() {
return;
//cout<<"- pp::dumpSummary curBuf="<<(void*)(currentBuffer());
#ifdef FLEX_DEBUG // Else peeking at internals may cause portability issues
ussize_t left = (yy_n_chars
- (yy_c_buf_p
-currentBuffer()->yy_ch_buf));
// cout<<" left="<<dec<<left;
#endif
cout<<endl;
}
int VPreLex::getBufSize()
{
return (yy_n_chars - (yy_c_buf_p-currentBuffer()->yy_ch_buf));
}
void VPreLex::dumpStack() {
// For debug use
return;
dumpSummary();
stack<VPreStream*> tmpstack = LEXP->m_streampStack;
while (!tmpstack.empty()) {
VPreStream* streamp = tmpstack.top();
cout<<"- bufferStack["<<(void*)(streamp)<<"]: "
<<" at="<<streamp->m_curFilelinep
<<" nBuf="<<streamp->m_buffers.size()
<<" size0="<<(streamp->m_buffers.empty() ? 0 : streamp->m_buffers.front().length())
<<(streamp->m_eof?" [EOF]":"")
<<(streamp->m_file?" [FILE]":"");
cout<<endl;
tmpstack.pop();
}
}
string VPreLex::cleanDbgStrg(const string& in) {
string out = in;
string::size_type pos;
while ((pos=out.find("\n")) != string::npos) { out.replace(pos, 1, "\\n"); }
while ((pos=out.find("\r")) != string::npos) { out.replace(pos, 1, "\\r"); }
return out;
}
void VPreLex::unused() {
if (0) {
// Prevent unused warnings
yy_top_state();
}
}
void VPreLex::initBuffer(const string & buf) {
m_bufferState = yy_create_buffer(NULL, YY_BUF_SIZE);
yy_switch_to_buffer(m_bufferState);
yyrestart(NULL);
scanBytes(buf);
}
/*###################################################################
* Local Variables:
* mode: C++
* End:
*/
......@@ -44,6 +44,7 @@
#include "filedef.h"
#include "namespacedef.h"
#include "membergroup.h"
#include "verilogdocgen.h"
//-----------------------------------------------------------------------------
......@@ -311,7 +312,7 @@ QCString ClassDef::displayName(bool includeScope) const
SrcLangExt lang = getLanguage();
//static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
QCString n;
if (lang==SrcLangExt_VHDL)
if (lang==SrcLangExt_VHDL || lang==SrcLangExt_VERILOG)
{
n = VhdlDocGen::getClassName(this);
}
......@@ -418,7 +419,7 @@ void ClassDef::internalInsertMember(MemberDef *md,
//printf("insertInternalMember(%s) isHidden()=%d\n",md->name().data(),md->isHidden());
if (md->isHidden()) return;
if (getLanguage()==SrcLangExt_VHDL)
if (getLanguage()==SrcLangExt_VHDL || getLanguage()==SrcLangExt_VERILOG)
{
QCString title=VhdlDocGen::trVhdlType(md->getMemberSpecifiers(),FALSE);
if (!m_impl->vhdlSummaryTitles.find(title))
......@@ -1476,7 +1477,13 @@ void ClassDef::endMemberDeclarations(OutputList &ol)
static bool inlineInheritedMembers = Config_getBool("INLINE_INHERITED_MEMB");
if (!inlineInheritedMembers && countAdditionalInheritedMembers()>0)
{
ol.startMemberHeader("inherited");
if(Config_getBool("OPTIMIZE_OUTPUT_VERILOG"))
{
ol.endMemberSections();
return;
}
ol.startMemberHeader("inherited");
ol.parseText(theTranslator->trAdditionalInheritedMembers());
ol.endMemberHeader();
writeAdditionalInheritedMembers(ol);
......@@ -1857,9 +1864,12 @@ void ClassDef::writeDeclarationLink(OutputList &ol,bool &found,const char *heade
{
ol.parseText(header);
}
else if (lang==SrcLangExt_VHDL)
else if (lang==SrcLangExt_VHDL || lang==SrcLangExt_VERILOG)
{
ol.parseText(VhdlDocGen::trVhdlType(VhdlDocGen::ARCHITECTURE,FALSE));
if(lang==SrcLangExt_VERILOG)
ol.parseText("Modules");
else
ol.parseText(VhdlDocGen::trVhdlType(VhdlDocGen::ARCHITECTURE,FALSE));
}
else
{
......@@ -1876,6 +1886,10 @@ void ClassDef::writeDeclarationLink(OutputList &ol,bool &found,const char *heade
QCString ctype = compoundTypeString();
QCString cname = displayName(!localNames);
if(lang==SrcLangExt_VERILOG)
ctype=VhdlDocGen::getProtectionName((VhdlDocGen::VhdlClasses)protection());
if (lang!=SrcLangExt_VHDL) // for VHDL we swap the name and the type
{
ol.writeString(ctype);
......@@ -2436,7 +2450,7 @@ void ClassDef::writeMemberList(OutputList &ol)
{
ol.writeString("<span class=\"mlabel\">");
QStrList sl;
if (lang==SrcLangExt_VHDL)
if (lang==SrcLangExt_VHDL || lang==SrcLangExt_VERILOG)
{
sl.append(VhdlDocGen::trVhdlType(md->getMemberSpecifiers())); //append vhdl type
}
......
......@@ -1441,6 +1441,7 @@ void Config::check()
filePatternList.append("*.for");
filePatternList.append("*.vhd");
filePatternList.append("*.vhdl");
filePatternList.append("*.v");
filePatternList.append("*.tcl");
filePatternList.append("*.md");
filePatternList.append("*.markdown");
......@@ -1463,6 +1464,7 @@ void Config::check()
filePatternList.append("*.PY");
filePatternList.append("*.F90");
filePatternList.append("*.F");
filePatternList.append("*.V");
filePatternList.append("*.VHD");
filePatternList.append("*.VHDL");
filePatternList.append("*.TCL");
......@@ -1582,6 +1584,11 @@ void Config::check()
annotationFromBrief.append("an");
annotationFromBrief.append("the");
}
if (Config_getBool("OPTIMIZE_OUTPUT_VERILOG"))
{
Config_getBool("OPTIMIZE_OUTPUT_VHDL") = TRUE;
}
// some default settings for vhdl
if (Config_getBool("OPTIMIZE_OUTPUT_VHDL") &&
......
......@@ -577,6 +577,21 @@ Go to the <a href="commands.html">next</a> section or return to the
<![CDATA[
Set the \c OPTIMIZE_OUTPUT_VHDL tag to \c YES if your project consists of VHDL
sources. Doxygen will then generate output that is tailored for VHDL.
]]>
</docs>
</option>
<option type='bool' id='OPTIMIZE_OUTPUT_VERILOG' defval='0'>
<docs>
<![CDATA[
Set the \c OPTIMIZE_OUTPUT_VERILOG tag to \c YES if your project consists of VERILOG
sources. Doxygen will then generate output that is tailored for VERILOG.
]]>
</docs>
</option>
<option type='bool' id='HIDE_PORT' defval='0'>
<docs>
<![CDATA[
Set the \c HIDE_PORT tag to \c YES ports are not displayed.
]]>
</docs>
</option>
......@@ -1306,6 +1321,8 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn"
<value name='*.tcl'/>
<value name='*.vhd'/>
<value name='*.vhdl'/>
<value name='*.v'/>
<value name='*.V'/>
<value name='*.ucf'/>
<value name='*.qsf'/>
<value name='*.as'/>
......
......@@ -25,7 +25,7 @@
#include <stdlib.h>
#include <sys/stat.h>
#include <qtextcodec.h>
#include <unistd.h>
//#include <unistd.h>
#include <errno.h>
#include <qptrdict.h>
#include <qtextstream.h>
......@@ -99,6 +99,8 @@
#include "settings.h"
#include "context.h"
#include "fileparser.h"
#include "VPreProc.h"
#include "verilogscanner.h"
// provided by the generated file resources.cpp
extern void initResources();
......@@ -9330,7 +9332,7 @@ static ParserInterface *getParserForFile(const char *fn)
{
extension = ".no_extension";
}
fprintf(stderr,"\n search parse for extension \n",extension.data());
return Doxygen::parserManager->getParser(extension);
}
......@@ -9357,15 +9359,44 @@ static void parseFile(ParserInterface *parser,
QFileInfo fi(fileName);
BufStr preBuf(fi.size()+4096);
bool jk=Config_getBool("ENABLE_PREPROCESSING");
bool ks=parser->needsPreprocessing(extension);
msg("parse file mit extension %s %s %d %d",extension.data(),parser->name.data(),jk,ks);
if (Config_getBool("ENABLE_PREPROCESSING") &&
parser->needsPreprocessing(extension))
{
BufStr inBuf(fi.size()+4096);
msg("Preprocessing %s...\n",fn);
fprintf(stderr,"\nPreprocessing %s...\n",fn);
BufStr strBuf(fi.size()+4096);
SrcLangExt lang = getLanguageFromFileName(fn);
bool optVerilog = lang==SrcLangExt_VHDL || lang==SrcLangExt_VERILOG;
if(optVerilog)
{
VerilogPreProc defProc;
readInputFile(fileName,strBuf);
QCString s=defProc.performPreprocessing(fi,true).data();
#if 0
// deleteVerilogChars(bb,"\0");
printf("\n++++++++++++++++######++++++++++++++++++++++++++++");
printf("\n %s",s.data());
printf("\n+++++++++++++++++++++++++++++++++++++");
// exit(0);
// defProc.printDict();
#endif
preBuf.addArray(s.data(),s.length());
}
else
{
readInputFile(fileName,inBuf);
preprocessFile(fileName,inBuf,preBuf);
}
}
else // no preprocessing
{
msg("Reading %s...\n",fn);
......@@ -9479,8 +9510,9 @@ static void parseFiles(Entry *root,EntryNav *rootNav)
QStrList filesInSameTu;
FileDef *fd=findFileDef(Doxygen::inputNameDict,s->data(),ambig);
ASSERT(fd!=0);
ParserInterface * parser = getParserForFile(s->data());
parser->startTranslationUnit(s->data());
parser->startTranslationUnit(s->data());
parseFile(parser,root,rootNav,fd,s->data(),FALSE,filesInSameTu);
}
}
......@@ -10013,6 +10045,8 @@ void initDoxygen()
Doxygen::parserManager->registerParser("dbusxml", new DBusXMLScanner);
Doxygen::parserManager->registerParser("tcl", new TclLanguageScanner);
Doxygen::parserManager->registerParser("md", new MarkdownFileParser);
Doxygen::parserManager->registerParser("v", new VerilogScanner("verilog"));
// register any additional parsers here...
......
......@@ -47,6 +47,8 @@
#include "classlist.h"
#include "namespacedef.h"
#include "filename.h"
#include "verilogdocgen.h"
#define MAX_ITEMS_BEFORE_MULTIPAGE_INDEX 200
#define MAX_ITEMS_BEFORE_QUICK_INDEX 30
......@@ -434,7 +436,7 @@ static void writeClassTree(OutputList &ol,const BaseClassList *bcl,bool hideSupe
}
bool b;
if (cd->getLanguage()==SrcLangExt_VHDL)
if (cd->getLanguage()==SrcLangExt_VHDL || cd->getLanguage()==SrcLangExt_VERILOG)
{
b=hasVisibleRoot(cd->subClasses());
}
......@@ -509,7 +511,7 @@ static void writeClassTree(OutputList &ol,const BaseClassList *bcl,bool hideSupe
//printf("Class %s at %p visited=%d\n",cd->name().data(),cd,cd->visited);
bool wasVisited=cd->visited;
cd->visited=TRUE;
if (cd->getLanguage()==SrcLangExt_VHDL)
if (cd->getLanguage()==SrcLangExt_VHDL|| cd->getLanguage()==SrcLangExt_VERILOG)
{
writeClassTree(ol,cd->baseClasses(),wasVisited,level+1,ftv,addToIndex);
}
......@@ -809,7 +811,7 @@ static void writeClassTreeForList(OutputList &ol,ClassSDict *cl,bool &started,FT
// cd->isVisibleInHierarchy()
// );
bool b;
if (cd->getLanguage()==SrcLangExt_VHDL)
if (cd->getLanguage()==SrcLangExt_VHDL || cd->getLanguage()==SrcLangExt_VERILOG)
{
if ((VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS)
{
......@@ -875,7 +877,7 @@ static void writeClassTreeForList(OutputList &ol,ClassSDict *cl,bool &started,FT
ftv->addContentsItem(hasChildren,cd->displayName(),0,0,0,FALSE,FALSE,cd);
}
}
if (cd->getLanguage()==SrcLangExt_VHDL && hasChildren)
if ((cd->getLanguage()==SrcLangExt_VHDL || cd->getLanguage()==SrcLangExt_VERILOG ) && hasChildren)
{
writeClassTree(ol,cd->baseClasses(),cd->visited,1,ftv,addToIndex);
cd->visited=TRUE;
......@@ -2267,7 +2269,12 @@ void addClassMemberNameToIndex(MemberDef *md)
static bool hideFriendCompounds = Config_getBool("HIDE_FRIEND_COMPOUNDS");
ClassDef *cd=0;
if ( md->getLanguage()==SrcLangExt_VERILOG) // && (VhdlDocGen::isRecord(md) || VhdlDocGen::isUnit(md)))
{
VerilogDocGen::adjustMemberName(md);
}
if (md->isLinkableInProject() &&
(cd=md->getClassDef()) &&
......
......@@ -122,6 +122,12 @@ HEADERS = arguments.h \
xmlgen.h \
docbookvisitor.h \
docbookgen.h \
verilogscanner.h \
verilogdocgen.h \
verilogparser.hpp \
VFileLine.h \
VPreLex.h \
VPreProc.h \
vhdljjparser.h
......@@ -206,9 +212,16 @@ SOURCES = arguments.cpp \
docbookvisitor.cpp \
docbookgen.cpp \
vhdljjparser.cpp \
verilogparser.cpp \
verilogdocgen.cpp \
VFileLine.cpp \
VPreProc.cpp \
../generated_src/doxygen/ce_parse.cpp \
../generated_src/doxygen/constexp.cpp \
../generated_src/doxygen/vhdlcode.cpp \
../generated_src/doxygen/verilogscanner.cpp \
../generated_src/doxygen/VPreLex.cpp \
../generated_src/doxygen/code.cpp \
../generated_src/doxygen/commentcnv.cpp \
../generated_src/doxygen/commentscan.cpp \
......
......@@ -110,6 +110,17 @@ sub GenerateLex {
#$ GenerateDep("\$(GENERATED_SRC)/ce_parse.h","constexp.y");
$(YACC) -l -d -p ce_parsexpYY constexp.y -o \$(GENERATED_SRC)/ce_parse.c
-rm $(GENERATED_SRC)/ce_parse.c
#$ GenerateDep("verilogscanner.cpp","verilogscanner.l");
$(LEX) -8 -PverilogScanYY -t verilogscanner.l | $(INCBUFSIZE) >verilogscanner.cpp
#$ GenerateDep("verilogparser.cpp","verilogparser.y");
$(YACC) -v -d verilogparser.y -o verilogparser.cpp
#$ GenerateDep("VPreLex.cpp","VPreLex.l");
$(LEX) -PVPreLex -t VPreLex.l | $(INCBUFSIZE) >VPreLex.cpp
#$ GenerateDep("layout.cpp","\$(GENERATED_SRC)/layout_default.xml.h");
......
......@@ -1943,8 +1943,9 @@ void MemberDef::getLabels(QStrList &sl,Definition *container) const
//ol.writeLatexSpacing();
//ol.startTypewriter();
//ol.docify(" [");
SrcLangExt lang = getLanguage();
bool optVhdl = lang==SrcLangExt_VHDL;
SrcLangExt lang = getLanguage();
bool optVhdl = lang==SrcLangExt_VHDL || lang==SrcLangExt_VERILOG;
bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");
if (optVhdl)
{
......@@ -2532,7 +2533,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
SrcLangExt lang = getLanguage();
//printf("member=%s lang=%d\n",name().data(),lang);
bool optVhdl = lang==SrcLangExt_VHDL;
bool optVhdl = (lang==SrcLangExt_VHDL) || (lang==SrcLangExt_VERILOG);
QCString sep = getLanguageSpecificSeparator(lang,TRUE);
QCString scopeName = scName;
......
......@@ -130,7 +130,7 @@ class ParserInterface
* comment block parser was invoked.
*/
virtual void parsePrototype(const char *text) = 0;
QCString name;
};
//-----------------------------------------------------------------------------
......@@ -174,9 +174,9 @@ class ParserManager
bool registerExtension(const char *extension, const char *parserName)
{
if (parserName==0 || extension==0) return FALSE;
ParserInterface *intf = m_parsers.find(parserName);
if (intf==0) return FALSE;
if (m_extensions.find(extension)!=0) // extension already exists
ParserInterface *intf = m_parsers.find(parserName);
if (intf==0) return FALSE;
if (m_extensions.find(extension)!=0) // extension already exists
{
m_extensions.remove(extension); // remove it
}
......@@ -193,9 +193,10 @@ class ParserManager
QCString ext = QCString(extension).lower();
if (ext.isEmpty()) ext=".no_extension";
ParserInterface *intf = m_extensions.find(ext);
if (intf==0 && ext.length()>4)
// fprintf(stderr,"\n get parser for extension %s \n",ext.data());
if (intf==0 && ext.length()>4)
{
intf = m_extensions.find(ext.left(4));
intf = m_extensions.find(ext.left(4));
}
return intf ? intf : m_defaultParser;
}
......
......@@ -1853,15 +1853,26 @@ class TranslatorEnglish : public Translator
/*! Used file list for a Java enum */
virtual QCString trEnumGeneratedFromFiles(bool single)
{ QCString result = "The documentation for this enum was generated from the following file";
if (!single) result += "s";
{
QCString result;
if(Config_getBool("OPTIMIZE_OUTPUT_VERILOG"))
result = "The documentation for this module was generated from the following file";
else
result = "The documentation for this enum was generated from the following file";
if (!single) result += "s";
result+=":";
return result;
}
/*! Header of a Java enum page (Java enums are represented as classes). */
virtual QCString trEnumReference(const char *name)
{ return QCString(name)+" Enum Reference"; }
{
if(Config_getBool("OPTIMIZE_OUTPUT_VERILOG"))
return QCString(name)+" Module Reference";
return QCString(name)+" Enum Reference"; }
/*! Used for a section containing inherited members */
virtual QCString trInheritedFrom(const char *members,const char *what)
......
......@@ -54,7 +54,9 @@ enum SrcLangExt
SrcLangExt_VHDL = 0x02000,
SrcLangExt_XML = 0x04000,
SrcLangExt_Tcl = 0x08000,
SrcLangExt_Markdown = 0x10000
SrcLangExt_Markdown = 0x10000,
SrcLangExt_VERILOG = 0x20000
};
/** Grouping info */
......
......@@ -5139,7 +5139,7 @@ bool classHasVisibleChildren(ClassDef *cd)
{
BaseClassList *bcl;
if (cd->getLanguage()==SrcLangExt_VHDL) // reverse baseClass/subClass relation
if (cd->getLanguage()==SrcLangExt_VERILOG) // reverse baseClass/subClass relation
{
if (cd->baseClasses()==0) return FALSE;
bcl=cd->baseClasses();
......@@ -6744,7 +6744,10 @@ g_lang2extMap[] =
{ "vhdl", "vhdl", SrcLangExt_VHDL },
{ "dbusxml", "dbusxml", SrcLangExt_XML },
{ "tcl", "tcl", SrcLangExt_Tcl },
{ "md", "md", SrcLangExt_Markdown },
{ "ucf", "v", SrcLangExt_VERILOG },
{ "qsf", "v", SrcLangExt_VERILOG },
{ "v", "v", SrcLangExt_VERILOG },
{ "md", "md", SrcLangExt_Markdown },
{ 0, 0, (SrcLangExt)0 }
};
......@@ -6835,6 +6838,8 @@ void initDefaultExtensionMapping()
updateLanguageMapping(".ucf", "vhdl");
updateLanguageMapping(".qsf", "vhdl");
updateLanguageMapping(".md", "md");
updateLanguageMapping(".v", "v");
updateLanguageMapping(".V", "v");
updateLanguageMapping(".markdown", "md");
//updateLanguageMapping(".xml", "dbusxml");
......@@ -7832,6 +7837,7 @@ QCString langToString(SrcLangExt lang)
case SrcLangExt_Python: return "Python";
case SrcLangExt_Fortran: return "Fortran";
case SrcLangExt_VHDL: return "VHDL";
case SrcLangExt_VERILOG: return "VERILOG";
case SrcLangExt_XML: return "XML";
case SrcLangExt_Tcl: return "Tcl";
case SrcLangExt_Markdown: return "Markdown";
......@@ -7842,7 +7848,7 @@ QCString langToString(SrcLangExt lang)
/** Returns the scope separator to use given the programming language \a lang */
QCString getLanguageSpecificSeparator(SrcLangExt lang,bool classScope)
{
if (lang==SrcLangExt_Java || lang==SrcLangExt_CSharp || lang==SrcLangExt_VHDL || lang==SrcLangExt_Python)
if (lang==SrcLangExt_Java || lang==SrcLangExt_CSharp || lang==SrcLangExt_VERILOG || lang==SrcLangExt_VHDL || lang==SrcLangExt_Python)
{
return ".";
}
......
This source diff could not be displayed because it is too large. You can view the blob instead.
/******************************************************************************
* Copyright (c) M.Kreis,2009
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* cvb
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
* You may use and distribute this software under the terms of the
* GNU General Public License, version 2 or later
****************************************************************************/
/****************************************************************************
* Scanner for Verilog 2001 subset
* Date: 02/2009
* supports the IEEE Std 1364-2001 (Revision of IEEE Std 1364-1995)Verilog subset
* %option debug
*****************************************************************************/
%{
#include "VPreProc.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <ctype.h>
#include "commentscan.h"
#include "verilogscanner.h"
#include "doxygen.h"
#include "searchindex.h"
#include "verilogdocgen.h"
#include <ctype.h>
#include "scanner.h"
#include "vhdldocgen.h"
#include "util.h"
#include "verilogparser.hpp"
#include "bufstr.h"
#include "VPreProc.h"
#include "message.h"
#include "tooltip.h"
//--------------------------------------------------------------------------
// FEATURE1 [`]("accelerate"|"autoexpand_vectornets"|"celldefine"|"default_decay_time"|"default_nettype"|"default_trireg_strength"|"delay_mode_distributed"|"delay_mode_zero"|"disable_portfaults"|"enable_portfaults"|"endcelldefine"|"endprotect"|"expand_vectornets"|"inline"|"line"|"noaccelerate"|"noexpand_vectornets"|"noremove_gatenames"|"noremove_netnames"|"nosuppress_faults"|"nounconnected_drive"|"portcoerce"|"pragma"|"protect"|"protected"|"remove_gatenames"|"remove_netnames"|"resetall"|"suppress_faults"|"timescale")[^\n]*
// ("accelerate"|"autoexpand_vectornets"|"celldefine"|"default_decay_time"|"default_nettype"|"default_trireg_strength"|"delay_mode_distributed"|"delay_mode_zero"|"disable_portfaults"|"enable_portfaults"|"endcelldefine"|"endprotect"|"expand_vectornets"|"inline"|"line"|"noaccelerate"|"noexpand_vectornets"|"noremove_gatenames"|"noremove_netnames"|"nosuppress_faults"|"nounconnected_drive"|"portcoerce"|"pragma"|"protect"|"protected"|"remove_gatenames"|"remove_netnames"|"resetall"|"suppress_faults"|"timescale")[\n]*
static ParserInterface *g_thisParser;
static int ss1,ee1;
static int yyEndModLine=0;
static int yyEndModLine1;
static int yyLineNr =1;
static int yyPrevLine=1;
static int yyEndLine=1;
static char* g_buf;
static int inputPosition;
static Entry* curRoots;
static Entry gBlock;
static int num_chars;
static int defineLineContinue=0;
static int startComment;
static int iSize=0;
static QCString inputVerilogString;
static QFile inputFile;
static QCString yyFileName;
static QList<QCString> qlist;
// stores global variables like `define xxxx
static QDict<Entry> globalMemberList(1009);
static MyParserConv *pconv;
static QCString lastLetter;
static int totLines=0;
static bool multLineComment=false;
static bool doxComment=false; // doxygen comment ?
static QCString strComment;
static int iDocLine=-1;
// ----------------- <verilog-code > ----------------------------------
static QCString g_CurrClass;
static QCString g_tempComp;
static CodeOutputInterface * g_code;
static QCString g_curClassName;
static const char * g_inputString; //!< the code fragment as text
static int g_inputLines=0; //!<number of line in the code fragment
static bool g_needsTermination;
static QCString g_exampleName;
static QCString g_exampleFile;
static QCString g_CurrScope;
static FileDef * g_sourceFileDef;
static Definition * g_currentDefinition;
static MemberDef * g_currentMemberDef;
static bool g_includeCodeFragment;
static const char * g_currentFontClass;
static bool g_lexInit = FALSE;
static bool g_parseCode=FALSE;
static bool gInit=false;
static int iCodeLen;
static Definition *g_searchCtx;
// ------------------< functions for verilog code scanner >---------------
static void writeFont(const char *s,const char* text);
static void generateMemLink(CodeOutputInterface &ol,QCString &clName,QCString& memberName);
static bool writeColoredWord(QCString& word );
static void startCodeLine();
static bool generateClassOrGlobalLink(CodeOutputInterface &ol,char *clName, bool typeOnly=FALSE);
static bool generateMemLink(CodeOutputInterface &ol,QCString &clName,QCString& memberName,int type);
static void codifyLines(char *text,char *cl=NULL,bool undoc=false);
static void addToSearchIndex(const char *text);
static void writeMultiLineCodeLink(CodeOutputInterface &ol,
const char *ref,const char *file,
const char *anchor,const char *text,Definition *d);
static void startFontClass(const char *s);
static void endFontClass();
static void writeWord(char *word,char* curr_class=NULL);
//-------------------------------------------------------------------
static void parseGlobalMember();
static void parseLib(char *);
static QCString checkComment(QCString& q);
static void composeString(QCString& q);
static void writeInclude(QCString);
//-------------------------------------------------------------------
#define YY_NEVER_INTERACTIVE 1
#define YY_USER_ACTION num_chars +=verilogscannerYYleng ;
//-----------------------------------------------------------
// dictionaries for keywords
static QDict<QCString> verilogKeyDict(17,false);
static QDict<QCString> verilogGlobalDict(17,false);
static QDict<QCString> verilogDefineDict(17,false);
static const QCString g_verilogkeyword("vhdlkeyword");
static const QCString g_verilogDefinition("preprocessor");
static const char* VerilogKewWordMap[] = {"module","endmodule","input","output","inout","reg","parameter","always",
"case","endcase","if","begin","posedge","negedge","or","wire","tri","tri0","instance","use","design","config","endconfig","include","library","liblist",
"function","endfunction","assign","end","for","else","initial","integer","real","task",
"and","buf","bufif0","bufif1","casex","casez","cmos","deassign","default","defparam","disable",
"edge","endattribute","endprimitive","endspecify","endtable","endtask","event",
"force","forever","fork","force","forever","ifnone","join","large","macromodule","medium","Input","Output","Inout",
"nand","nmos","nor","not","notif0","notif1","localparam","cell",
"pmos","primitive","pull0","pull1","pullup","pulldown","automatic",
"rcmos","real","time","realtime","release","repeat","rnmos","rpmos","rtran","rtranif0","rtranif1",
"scalared","signed","small","specify","specparam","strength","strong0","strong1","supply0","supply1",
"table","tran","tranif0","tranif1","tri1","triand","trior","trireg","pulsestyle_ondetect", "showcancelled","noshowcancelled","pulsestyle_onevent",
"generate","endgenerate","genvar","unsigend","xor","xnor","wait","wand","weak0","weak1","while","wire","wor","vectored",""};
static const char* VerilogDefineMap[] =
{
"`accelerate",
"`autoexpand_vectornets" ,
"`celldefine",
"`default_decay_time,"
"`default_nettype",
"`default_trireg_strength",
"`delay_mode_distributed",
"`delay_mode_zero" ,
"`disable_portfaults",
"`enable_portfaults",
"`endcelldefine",
"`endprotect",
"`expand_vectornets",
"`inline",
"`line",
"`noaccelerate",
"`noexpand_vectornets",
"`noremove_gatenames",
"`noremove_netnames" ,
"`nosuppress_faults",
"`nounconnected_drive",
"`portcoerce",
"`pragma",
"`protect" ,//SV
"`protected",// SV
"`remove_gatenames",
"`remove_netnames",
"`resetall",
"`suppress_faults",
"`timescale",
"" };
// some but not all system words
static const char* VerilogKewWordMap1[] = {"$async$and$array","$async$and$plane","$async$nand$array", "$async$nand$plane","$async$or$array", "$async$or$plane",
"$async$nor$array", "$async$nor$plane","$sync$and$array", "$sync$and$plane","$sync$nand$array", "$sync$nand$plane",
"$sync$or$array", "$sync$or$plane","$sync$nor$array", "$sync$nor$plane","$display", "$strobe",
"$displayb", "$strobeb","$displayh", "$strobeh","$displayo","$strobeo","$monitor", "$write","$monitorb", "$writeb",
"$monitorh", "$writeh","$monitoro", "$writeo","$monitoroff", "$monitoron","$fclose", "$fopen","$fdisplay", "$fstrobe",
"$fdisplayb", "$fstrobeb","$fdisplayh", "$fstrobeh","$fdisplayo", "$fstrobeo","$fgetc", "$ungetc","$fflush", "$ferror",
"$fgets", "$rewind","$fmonitor", "$fwrite","$fmonitorb", "$fwriteb","$fmonitorh", "$fwriteh",
"$fmonitoro", "$fwriteo","$readmemb", "$readmemh","$swrite", "$swriteb","$swriteo", "$swriteh",
"$sformat", "$sdf_annotate","$fscanf", "$sscanf","$fread", "$ftell","$fseek", "$printtimescale",
"$timeformat" ,"$finish", "$stop", "$realtime","$stime", "$time","$bitstoreal", "$realtobits",
"$itor", "$rtoi","$signed", "$unsigned","$test$plusargs", "$value$plusargs","$q_initialize", "$q_add",
"$q_remove", "$q_full","$q_exam","$period","$hold","$setup","$width","$skew","$reovery","$nochange","$timeskew","$setuphold","$fullskew",""};
void deleteVerilogChars(QCString &s,const char* c)
{
int index=s.findRev(c,-1,FALSE);
while (index > -1)
{
QCString qcs=s.remove(index,1);
s=qcs;
index=s.findRev(c,-1,FALSE);
}
}
static void startCodeBlock(int index){
int ll=strComment.length();
iCodeLen=inputVerilogString.findRev(strComment.data())+ll;
//fprintf(stderr,"\n startin code..%d %d %d\n",iCodeLen,num_chars,ll);
//assert(false);
gBlock.reset();
int len=strComment.length();
QCString name=strComment.right(len-index);//
name=VhdlDocGen::getIndexWord(name.data(),1);
if(!name)
gBlock.name="misc"+ VhdlDocGen::getRecordNumber();
else
gBlock.name=name;
strComment=strComment.left(index);
gBlock.startLine=yyLineNr+1;
gBlock.bodyLine=yyLineNr+1;
VhdlDocGen::prepareComment(strComment);
gBlock.brief+=strComment;
}
static void makeInlineDoc(int endCode)
{
int len=endCode-iCodeLen;
QCString par=inputVerilogString.mid(iCodeLen,len);
gBlock.doc=par;
gBlock.inbodyDocs=par;
gBlock.section=Entry::VARIABLE_SEC;
gBlock.spec=VhdlDocGen::MISCELLANEOUS;
gBlock.fileName = yyFileName;
gBlock.endBodyLine=yyLineNr-1;
gBlock.lang=SrcLangExt_VHDL;
gBlock.fileName =yyFileName;
gBlock.lang=SrcLangExt_VHDL;
Entry *temp=new Entry(gBlock);
Entry* compound= getCurrVerilog();
// fprintf(stderr,"\n <<<%s %s \n %s \n %d %d %d\n\n>>>\n",compound->name.data(),gBlock.brief.data(),par.data(),endCode,iCodeLen,yyLineNr);
if(compound)
compound->addSubEntry(temp);
else
{
temp->type="misc"; // global code like library ieee...
curRoots->addSubEntry(temp);
}
gBlock.reset();
strComment.resize(0);
resetVerilogBrief();
}// makeInlineDoc
static bool isConstraintFile(QCString fileName,char *type)
{
int i=fileName.findRev(type);
int j=fileName.length();
int k=strlen(type);
if((i+k)==j)
return true;
return false;
}
static bool checkMultiComment(QCString& qcs){
QList<Entry> *pTemp=VerilogDocGen::getEntryAtLine1(curRoots,iDocLine);
if (!pTemp->isEmpty())
{
int ii=pTemp->count();
qcs.stripPrefix("//%");
while(!pTemp->isEmpty()){
Entry *e=(Entry*)pTemp->getFirst();
e->briefLine=yyLineNr;
e->brief+=qcs;
iDocLine=-1;
pTemp->removeFirst();
ii=pTemp->count();
}
return true;
}
return false;
}
void addGlobalVerilogMember(const Entry *e)
{
Entry *pNew=new Entry(*e);
globalMemberList.insert(pNew->name,pNew);
}
static bool checkString(QCString &name)
{
if (name.isEmpty()) return FALSE;
static QRegExp regg("[ \t\"]");
int len=name.length();
if (name.at(0)=='"' && name.at(len-1)=='"' && len > 2)
{
QStringList qrl=QStringList::split(regg,name,FALSE);
if (VhdlDocGen::isNumber(qrl[0].data()))
{
g_code->codify("\"");
startFontClass("vhdllogic");
QCString mid=name.mid(1,len-2); //" 1223 "
g_code->codify(mid.data());
endFontClass();
g_code->codify("\"");
}
else
{
startFontClass("keyword");
g_code->codify(name.data());
endFontClass();
}
return TRUE;
}
if (VhdlDocGen::isNumber(name))
{
startFontClass("vhdllogic");
g_code->codify(name.data());
endFontClass();
return TRUE;
}
return FALSE;
}
static bool writeColoredWord(QCString& temp ){
const QCString *ss=VerilogDocGen::findKeyWord(temp);
if (ss){
writeFont(ss->data(),temp.data());
return true;
}
return false;
}
static void writeSpecWord(const char *word,const char* curr_class=0,bool classLink=FALSE)
{
bool found=FALSE;
QCString temp;
QCString tclass(curr_class);
QCString ttt(word);
if (ttt.isEmpty()) return;
for (unsigned int j=0;j<ttt.length();j++)
{
char c=ttt.at(j);
if ( c==' '|| c==',' || c==';' || c==':' || c=='(' || c==')' || c=='\r' || c=='\t' || c=='.')
{
if (found)
{
if (!writeColoredWord(temp)) // is it a keyword ?
{
//if (VhdlDocGen::findKeyWord(temp))
// writeFont("vhdlkeyword",temp.data());
//printf("writeWord: %s\n",temp.data());
if (!tclass.isEmpty())
{
if (!classLink)
{
writeWord(temp.data());//(( generateMemLink(*g_code,tclass,temp); //
}
else
{
generateClassOrGlobalLink(*g_code,temp.data());
}
}
else
{
if (!checkString(temp))
g_code->codify(temp.data());
}
}
temp.resize(0);
found=FALSE;
}
char cc[2];
cc[0]=c;
cc[1]=0;
g_code->codify(cc);
}
else
{
found=TRUE;
temp+=c;
}
} // for
if (!temp.isEmpty())
{
if (!writeColoredWord(temp))
{
if (!tclass.isEmpty())
{
if (!classLink)
{
writeWord(temp.data());
// generateMemLink(*g_code,tclass,temp); // generateMemLink(*g_code,g_CurrClass,left);
}
else
{
generateClassOrGlobalLink(*g_code,temp.data());
}
}
else
{
QCString qc(temp.data());
if (VhdlDocGen::isNumber(qc)){
startFontClass("vhdllogic");
g_code->codify(temp.data());
endFontClass();
}
else
g_code->codify(temp.data());
}
}
}
}// writeWord
static void buildKeyMap()
{
int j=0;
verilogGlobalDict.setAutoDelete(true);
verilogKeyDict.setAutoDelete(true);
verilogDefineDict.setAutoDelete(true);
qlist.setAutoDelete(true);
globalMemberList.setAutoDelete(true);
QCString p=VerilogKewWordMap[0];
while(!p.isEmpty())
{
verilogKeyDict.insert(p,new QCString(p.data()));
p=VerilogKewWordMap[++j];
}
j=0;
p=VerilogKewWordMap1[0];
while(!p.isEmpty())
{
verilogGlobalDict.insert(p,new QCString(p.data()));
p=VerilogKewWordMap1[++j];
}
j=0;
p=VerilogDefineMap[0];
while(!p.isEmpty())
{
verilogDefineDict.insert(p,new QCString(p.data()));
p=VerilogDefineMap[++j];
}
}// buildKeypMap
const QCString* VerilogDocGen::findKeyWord(const char *str)
{
QCString word(str);
if (word.isEmpty() || word.at(0)=='\0') return 0;
if(verilogKeyDict.find(word))
return &g_verilogkeyword;
if(verilogGlobalDict.find(word))
return &g_verilogDefinition;
if(verilogDefineDict.find(word))
return &g_verilogDefinition;
return 0;
}
void writeVerilogFont(const char* col,const char* text)
{
writeFont(col,text);
}
// writes a coloured word to the output
static void writeVWord(QCString& qcs){
static bool stripComment=Config_getBool("STRIP_CODE_COMMENTS");
printf("\n 1. write %s...",qcs.data());
if(qcs.isEmpty())return;
QCString temp=qcs.copy();
if(qcs.stripPrefix("\n")){
codifyLines(temp.data());return;}
else if(qcs.stripPrefix(" "))
{g_code->codify(temp.data()); return;}
if(qcs.stripPrefix("\""))
{writeFont("keyword",temp.data());return;}
if(qcs.stripPrefix("//"))
{
if (stripComment && temp.contains(vlogComment))
{
yyLineNr+=temp.contains("\n");
return;
}
else {
printf("\n 2. write %s...",temp.data());
writeFont("keyword",temp.data());
}
return;
}
if(qcs.stripPrefix("")){
deleteVerilogChars(qcs,"");
deleteVerilogChars(qcs,"");
startFontClass("undoc");
codifyLines(qcs.data(),0,true);
endFontClass();
return;
}
if(qcs.stripPrefix("/*!"))
if( stripComment){
yyLineNr+=temp.contains("\n");
return;
}
else
qcs.prepend("/*");
if(qcs.stripPrefix("/*")){
startFontClass("keyword");
codifyLines(temp.data());
endFontClass();
return;
}
if(qcs.stripPrefix("`"))
{
qcs=temp;
if(qcs.stripPrefix("`define"))
{
writeFont("preprocessor","`define");
writeInclude(qcs);
return;
}
if(qcs.stripPrefix("`include"))
{
writeFont("preprocessor","`include");
writeInclude(qcs);
return;
}
writeFont("preprocessor",qcs.data());
return;
}//
const QCString *ss=VerilogDocGen::findKeyWord(qcs.data());
if (ss)
{writeFont(ss->data(),qcs.data());return;}
MemberDef* md=findGlobalMember(temp);
if(md)
{
g_code->writeCodeLink(md->getReference(),
md->getOutputFileBase(),
md->anchor(),
temp.data(),
md->briefDescriptionAsTooltip());
return;
}
QCString tempClass = getCurrVerilogParsingClass();
bool feat=generateVerilogMemLink(tempClass,temp,VerilogDocGen::FEATURE);
if(feat) return;
/*
if(!feat)
{
writeWord(qcs.data());
return;
}
*/
if(qcs.length()==1)
{codifyLines(qcs.data());return;}
if(qcs.stripPrefix("$"))
writeFont("vhdlkeyword",temp.data());
else writeWord(temp.data());
}//writeVWord
// writes the rest of the input buffer
void printVerilogBuffer(bool b)
{
QCString qbuffer;
uint len=qlist.count();
for(uint j=0;j<len;j++) {
QCString *qcs=(QCString*)qlist.at(j);
writeVWord(*qcs);
}//for
qlist.clear();
}//printVerilogBuffer
void writePrevVerilogWords(const QCString& qcs){
uint len=qlist.count();
uint v=0;
for(uint j=0;j<len;j++) {
QCString *word=(QCString*)qlist.getFirst();
printf("\n+++ %s",word->data());
//if(qcs.contains("`"))
// printVerilogStringList();
if(strcmp(qcs.data(),word->data()) != 0)
{
writeVWord(*word);
qlist.removeFirst();
}else {
// QCString *wsord=(QCString*)qlist.getFirst();
qlist.removeFirst();
v=j;
break;
}
}//for
} // writePrevVerilogWords
// only for debugging
void printVerilogStringList()
{
QCString qbuffer;
int len=qlist.count();
for(int j=0;j<len;j++) {
QCString *qcs=(QCString*)qlist.at(j);
qbuffer+=qcs->data();
}
fprintf(stderr,"\n[%s]",qbuffer.data());
}
void codifyVerilogString(char* c,char* color)
{
if(color==NULL)
g_code->codify(c);
else
writeFont(color,c);
}
bool generateVerilogMemLink(QCString &clName,QCString& memberName,int type)
{
return generateMemLink(*g_code,clName,memberName,type);
}
bool generateVerilogCompMemLink(QCString &cl,QCString& inst,QCString & key, bool b)
{
MemberDef *md=0;
md=VerilogDocGen::findInstMember(cl,inst,key,b);
if(md){
ClassDef *ddd=md->getClassDef();
QCString nkll=md->getOutputFileBase();
QCString nklll=ddd->name();
}
if (md && md->isLinkable()) // is it a linkable class
{
if(!cl.isEmpty())
{
writeMultiLineCodeLink(*g_code,md->getReference(),md->getOutputFileBase(),md->anchor(),md->name(),md);
return true;
}
/*
if(b && !inst.isEmpty())
{
writeMultiLineCodeLink(*g_code,md->getReference(),md->getOutputFileBase(),md->anchor(),inst,md);
return true;
}
*/
}
return false;
}
static bool generateMemLink(CodeOutputInterface &ol,QCString &clName,QCString& memberName,int type)
{
if(clName.isEmpty() || memberName.isEmpty()) return false;
if((memberName.length()==1) && (isalpha(memberName.at(0))==0))
return false;
bool isLocal=false;
MemberDef *md=0;
if(memberName.contains('`'))
isLocal=true;
md=VerilogDocGen::findMember(clName,memberName,type);
// if(md==0)
// md=VerilogDocGen::findMember(clName,memberName,-1);
if (md && md->isLinkable()) // is it a linkable class
{
addToSearchIndex(memberName);
if(isLocal) memberName.prepend("`");
writeMultiLineCodeLink(ol,md->getReference(),md->getOutputFileBase(),md->anchor(),memberName,md);
return true;
}
addToSearchIndex(memberName);
return false;
}// generateMemLink
static void endCodeLine()
{
if (g_currentFontClass) { g_code->endFontClass(); }
g_code->endCodeLine();
}
static void addToSearchIndex(const char *text)
{
if (Doxygen::searchIndex)
{
Doxygen::searchIndex->addWord(text,FALSE);
}
}
/*! writes a link to a fragment \a text that may span multiple lines, inserting
* line numbers for each line. If \a text contains newlines, the link will be
* split into multiple links with the same destination, one for each line.
*/
static void writeMultiLineCodeLink(CodeOutputInterface &ol,
const char *ref,const char *file,
const char *anchor,const char *text,Definition *d)
{
static bool sourceTooltips = Config_getBool("SOURCE_TOOLTIPS");
TooltipManager::instance()->addTooltip(d);
bool done=FALSE;
char *p=(char *)text;
QCString tooltip;
if (!sourceTooltips) // fall back to simple "title" tooltips
{
tooltip = d->briefDescriptionAsTooltip();
}
while (!done)
{
char *sp=p;
char c;
while ((c=*p++) && c!='\n');
if (c=='\n')
{
yyLineNr++;
*(p-1)='\0';
// printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
ol.writeCodeLink(ref,file,anchor,sp,tooltip);
endCodeLine();
if (yyLineNr<g_inputLines)
{
startCodeLine();
}
}
else
{
// printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
ol.writeCodeLink(ref,file,anchor,sp,0);
done=TRUE;
}
}
}
bool generateVerilogClassOrGlobalLink(char *clName)
{
return generateClassOrGlobalLink(*g_code,clName,FALSE);
}
static bool generateClassOrGlobalLink(CodeOutputInterface &ol,char *clName, bool typeOnly)
{
QCString className=QCString(clName);
if(className.isEmpty()) return false;
ClassDef *cd=0;
cd = getClass(className.data());
if (cd && cd->isLinkable()) // is it a linkable class
{
QCString temp=cd->displayName();
// ol.linkableSymbol(yyLineNr,temp,cd, g_currentMemberDef ? g_currentMemberDef : g_currentDefinition);
writeMultiLineCodeLink(ol,cd->getReference(),cd->getOutputFileBase(),0,temp,cd);
addToSearchIndex(className);
return true;
}
return false;
}// generateClassOrGLink
static void startFontClass(const char *s)
{
if(s==NULL) return;
g_code->startFontClass(s);
g_currentFontClass=s;
}
static void writeFont(const char *s,const char* text)
{
if(s==NULL) return;
g_code->startFontClass(s);
g_code->codify(text);
g_code->endFontClass();
}
/*! counts the number of lines in the input */
static int countLines()
{
const char *p=inputVerilogString.data();
char c;
int count=1;
while ((c=*p))
{
p++ ;
if (c=='\n') count++;
}
if (p>g_inputString && *(p-1)!='\n')
{ // last line does not end with a \n, so we add an extra
// line and explicitly terminate the line after parsing.
count++,
g_needsTermination=TRUE;
}
return count;
}
/*! writes a word to the output.
* If curr_class is defined, the word belongs to a class
* and will be linked.
*/
static void writeWord(char *word,char* curr_class)
{
if(word==NULL)return;
const QCString *ss=VerilogDocGen::findKeyWord(word);
if(ss)
writeFont(ss->data(),word);
else{
QCString w(word);
if(!checkString(w))
g_code->codify(word);
}
return;
}// writeWord
/*! write a code fragment `text' that may span multiple lines, inserting
* line numbers for each line.
*/
static void codifyLines(char *text,char *cl,bool undoc)
{
// printf("codifyLines(%d,\"%d\")\n",yyLineNr,strlen(text));
if(text==NULL) return;
char *p=text,*sp=p;
char c;
bool done=FALSE;
while (!done)
{
sp=p;
while ((c=*p++) && c!='\n');
if (c=='\n')
{
yyLineNr++;
*(p-1)='\0';
if(!undoc)
writeWord(sp,cl);
else
g_code->codify(sp);
endCodeLine();
if (yyLineNr<g_inputLines)
{
startCodeLine();
}
}
else
{
writeWord(sp,cl);
done=TRUE;
}
}
}
static void setCurrentDoc(QCString &anchor)
{
if (Doxygen::searchIndex)
{
if (g_searchCtx)
{
Doxygen::searchIndex->setCurrentDoc(g_searchCtx,g_searchCtx->anchor(),FALSE);
}
else
{
Doxygen::searchIndex->setCurrentDoc(g_sourceFileDef,anchor,TRUE);
}
}
}
/*! start a new line of code, inserting a line number if g_sourceFileDef
* is TRUE. If a definition starts at the current line, then the line
* number is linked to the documentation of that definition.
*/
static void startCodeLine()
{
//if (g_currentFontClass) { g_code->endFontClass(); }
bool isLine;
if(ss1>ee1)
isLine=true;
else
isLine=false;
if (g_sourceFileDef)
{
// if((yyLineNr % 500) == 0)
// fprintf(stderr,"\r parsing line %d:",yyLineNr);
Definition *d = g_sourceFileDef->getSourceDefinition(yyLineNr);
// printf("startCodeLine %d d=%s\n", yyLineNr,d ? d->name().data() : "<null>");
if (!g_includeCodeFragment && d)
{
g_currentDefinition = d;
g_currentMemberDef = g_sourceFileDef->getSourceMember(yyLineNr);
if(!g_tempComp.isEmpty() && g_currentMemberDef )
{
// ClassDef *cf=VhdlDocGen::getClass(g_tempComp.data());
QCString nn=g_currentMemberDef->name();
MemberDef* mdeff=VhdlDocGen::findMember(g_tempComp,nn);
if(mdeff)
g_currentMemberDef=mdeff;
}
QCString lineAnchor;
lineAnchor.sprintf("l%05d",yyLineNr);
if (g_currentMemberDef)
{
g_code->writeLineNumber(g_currentMemberDef->getReference(),
g_currentMemberDef->getOutputFileBase(),
g_currentMemberDef->anchor(),yyLineNr);
setCurrentDoc( lineAnchor);
}
else if (d->isLinkableInProject())
{
g_code->writeLineNumber(d->getReference(),
d->getOutputFileBase(),
0,yyLineNr);
setCurrentDoc(lineAnchor);
}
}
else
{
g_code->writeLineNumber(0,0,0,yyLineNr);
}
}
g_code->startCodeLine(yyLineNr);
if (g_currentFontClass)
{
g_code->startFontClass(g_currentFontClass);
}
}
static void endFontClass()
{
if (g_currentFontClass)
{
g_code->endFontClass();
g_currentFontClass=0;
}
}
//---------------------------------------------------------------
static void addText(char* c,int len);
static void addToken(char c);
static int startLex();
static void resetScanner(const char* s,MyParserConv* parse);
#undef YY_INPUT
#define YY_INPUT(buf,result,max_size) result=verilogscannerYYread(buf,max_size);
static int verilogscannerYYread(char *buf,int max_size)
{
int c=0;
while ( c < max_size && inputVerilogString.at(inputPosition) )
{
*buf = inputVerilogString.at(inputPosition++) ;
c++; buf++;
}
return c;
}
// checks if we have found a correct parsed word or
// part of a word like (reg)ister
static bool check(bool bb=true)
{
char c=yy_hold_char;
if(iSize==0){
if(g_parseCode){
qlist.append(new QCString(verilogscannerYYtext));
}
return true;
}
/*
QCString qt(verilogscannerYYtext);
qt=qt.lower();
if(strcmp(qt.data(),verilogscannerYYtext)!=0)
return false;
*/
char d = g_buf[iSize-1];
int l=isdigit(c);
int k=isdigit(d);
if(k!=0 || l!=0 || d=='$') return false;
l=islower(c);
k=islower(d);
if(k!=0 || l!=0)
return false;
l=isupper(c);
k=isupper(d);
if(k!=0 || l!=0)
return false;
if(c=='_' || d=='_') return false;
if(g_parseCode){
qlist.append(new QCString(verilogscannerYYtext));
}
return true;
}
static void parseToken(const char* s){
if(g_parseCode)
qlist.append(new QCString(verilogscannerYYtext));
c_lval.ctype=s[0];
addToken(s[0]);
}
%}
/* --CopyLine>"\\"\r?/\n { // strip line continuation characters------------ VERLIOG SECTION -----------------------------------*/
WORD [a-zA-Z0-9_]+
LL [ \t]
LF [ \t\n]
COMMENT "//"[^\n]*
COMMENT1 "//!"[^\n]*
MIT [^\\\n]*
STRING ["][^"]*["]
FEATURE ("`include"|"`define"|"`ifndef"|"`endif"|"`elsif"|"`ifdef"|"`else"|"`undef")[^\n]*
FEATURE1 [`]("accelerate"|"autoexpand_vectornets"|"celldefine"|"default_decay_time"|"default_nettype"|"default_trireg_strength"|"delay_mode_distributed"|"delay_mode_zero"|"disable_portfaults"|"enable_portfaults"|"endcelldefine"|"endprotect"|"expand_vectornets"|"inline"|"line"|"noaccelerate"|"noexpand_vectornets"|"noremove_gatenames"|"noremove_netnames"|"nosuppress_faults"|"nounconnected_drive"|"portcoerce"|"pragma"|"protect"|"protected"|"remove_gatenames"|"remove_netnames"|"resetall"|"suppress_faults"|"timescale")[^\n]*
FEATUREX [`][a-zA-Z0-9_]+[^\n]*
SIGNEDBASE ['][sS][oOhHbBdD]
BASE ("'b"|"'B"|"'o"|"'O"|"'d"|"'D"|"'h"|"'H"|{SIGNEDBASE})[ ]?
NETTYPE "wire"|"tri"|"tri1"|"supply0"|"wand"|"triand"|"tri0"|"supply1"|"wor"|"trior"|"trireg"
STRENGTH1 "supply1"|"strong1"|"pull1"|"weak1"|"highz1"
STRENGTH0 "supply0"|"strong0"|"pull0"|"weak0"|"highz0"
GATETYPE "and"|"nand"|"or"|"nor"|"xor"|"xnor"|"buf"|"bufif0"|"bufif1"|"not"|"notif0"|"notif1"|"pulldown"|"pullup"|"nmos"|"rnmos"|"pmos"|"rpmos"|"cmos"|"rcmos"|"tran"|"rtran"|"tranif0"|"rtranif0"|"tranif1"|"rtranif1"
%option noyywrap
/*
language parsing states
*/
%x Start
%x Commentt
%x FindBegin
%x StartComment
%x tagComment
%x directive
%x specc
%x EndOfText
%%
. {
BEGIN(Start);
}
<EndOfText>[^\\\n]+ {
if(yy_hold_char=='\\')
{
if(g_parseCode)
qlist.append(new QCString(verilogscannerYYtext));
else
{
addText(verilogscannerYYtext,verilogscannerYYleng);
}
BEGIN(EndOfText);
}
else
{
if(!g_parseCode)
{
QCString s=verilogscannerYYtext;
addText(verilogscannerYYtext,verilogscannerYYleng);
parseGlobalMember();
vbufreset();
}
else{
qlist.append(new QCString(verilogscannerYYtext));
}
BEGIN(Start);
}
}
<EndOfText>[\\] {
if(g_parseCode)
{
char c=yy_hold_char;
qlist.append(new QCString("\\"));
if(yy_hold_char==32)
qlist.append(new QCString("\n"));
}
else{
addText(verilogscannerYYtext,verilogscannerYYleng);
// if(yy_hold_char==10)
// addText("?",1);
if(yy_hold_char==32)
yyLineNr++;
}
}
<Start>[][^]+[] {// grey out undefined code
QCString uu(verilogscannerYYtext);
if(g_parseCode)
{
// fprintf(stderr,"\n%s",uu.data());
qlist.append(new QCString(verilogscannerYYtext));
}
}
<Start>{FEATURE} {
// fprintf(stderr,"<[ %s ]>",verilogscannerYYtext);
QCString q(verilogscannerYYtext);
defineLineContinue=yyLineNr;
vbufreset();
if(!g_parseCode)
{
addText(verilogscannerYYtext,verilogscannerYYleng);
uint le=q.length()-1;
if(q.at(le)=='\\')
{
addText("?",1);
BEGIN(EndOfText);
} else{
parseGlobalMember();
vbufreset();
}
}
if(g_parseCode)
{
// VhdlDocGen::deleteAllChars(q,'');
uint le=q.length()-1;
bool newLine=(q.at(le)=='\\');
QCString com=checkComment(q);
// qlist.append(new QCString(q.data()));
if(!q.contains("`include"))
composeString(q);
else
qlist.append(new QCString(q.data()));
if(!com.isEmpty())
qlist.append(new QCString(com.data()));
if(newLine)
{
BEGIN(EndOfText);
}
}//if
}
<Start>{FEATURE1}|{FEATUREX} {
QCString s(verilogscannerYYtext);
s=s.stripWhiteSpace();
int j=s.find(" ");
if(j>0)
s=s.left(j);
QCString s1=s;
DefineDict* gDict=VerilogPreProc::getFileDefineDict();
VhdlDocGen::deleteAllChars(s,'`');
Define *def=gDict->find(s);
if(g_parseCode)
{
QCString *yy=0;
if(Config_getBool("MACRO_EXPANSION") && def)
{
yy=new QCString(def->definition.data());
// VhdlDocGen::deleteAllChars(*yy,'"');
}
else
yy=new QCString(verilogscannerYYtext);
c_lval.cstr[0]='\0';
qlist.append(yy);
}
else{
// s.stripPrefix("`");
if(!verilogDefineDict.find(s1))
{
if(!g_parseCode)
addText(verilogscannerYYtext,verilogscannerYYleng);
}
// if(!def) && !def->definition.isEmpty())
// if(Config_getBool("WARNINGS"))
// warn(yyFileName,yyLineNr,"\n macro %s is not defined",verilogscannerYYtext);
if(!verilogDefineDict.find(s1))
return LETTER_TOK;
}
}
<Start>"ifnone" {if(check()) return IFNONE_TOK;REJECT;}
<Start>"realtime" {if(check()) {yyPrevLine=yyLineNr;addText(verilogscannerYYtext,verilogscannerYYleng); return REALTIME_TOK;}REJECT;}
<Start>"design" {if(check()) return DESIGN_TOK;REJECT;}
<Start>"library"{LF}+[^;]+ { parseLib(verilogscannerYYtext);return LIBRARY_TOK; }
<Start>"config" {if(check()) return CONFIG_TOK;REJECT;}
<Start>"endconfig" { if(check()){return ENDCONFIG_TOK;} REJECT;}
<Start>"include" {if(check()) return INCLUDE_TOK;REJECT;}
<Start>"use" {if(check()) return USE_TOK;REJECT;}
<Start>"liblist" { if(check()) return LIBLIST_TOK;REJECT;}
<Start>"instance" {if(check()) return INSTANCE_TOK;REJECT;}
<Start>"cell" { if(check()) return CELL_TOK;REJECT;}
<Start>"showcancelled" {if(check()) return SHOWCANCEL_TOK;REJECT;}
<Start>"noshowcancelled" { if(check()) return NOSHOWCANCEL_TOK;REJECT;}
<Start>"pulsestyle_onevent" {if(check()) return PULSEONE_EVENT_TOK;REJECT;}
<Start>"pulsestyle_ondetect" { if(check()) return PULSEON_DETECT_TOK;REJECT;}
<Start>"edge" {if(check()) return EDGE_TOK;REJECT;}
<Start>"negedge" {if(check()) return NEGEDGE_TOK;REJECT;}
<Start>"posedge" { if(check()){return POSEDGE_TOK;} REJECT;}
<Start>"$fullskew" {if(check()) return FULLSKEW_TOK;REJECT;}
<Start>"$recrem" {if(check()) return RECREM_TOK;REJECT;}
<Start>"$removal" {if(check()) return REMOVAL_TOK;REJECT;}
<Start>"$timeskew" {if(check()) return TIMESKEW_TOK;REJECT;}
<Start>"$nochange" {if(check()) return NOCHANGE_TOK;REJECT;}
<Start>"$hold" {if(check()) return DHOLD_TOK;REJECT;}
<Start>"$setup" { if(check()) return DSETUP_TOK;REJECT;}
<Start>"$setuphold" {if(check()) return DSETUPHOLD_TOK;REJECT;}
<Start>"$recovery" {if(check()) return DRECOVERY_TOK;REJECT;}
<Start>"$skew" {if(check()) return DSKEW_TOK;REJECT;}
<Start>"$width" {if(check()) return DWIDTH_TOK;REJECT;}
<Start>"$period" {if(check()) return DPERIOD_TOK;REJECT;}
<Start>"time" { if(check()){yyPrevLine=yyLineNr; addText(verilogscannerYYtext,verilogscannerYYleng); return TIME_TOK;} REJECT; }
<Start>"specparam" {if(check()) return SPECPARAM_TOK;REJECT;}
<Start>"endspecify" {if(check()) return ENDSPECIFY_TOK;REJECT;}
<Start>"specify" { if(check()) return SPECIFY_TOK;REJECT;}
<Start>"end" { if(check()) { yyEndLine=yyLineNr; strncpy(c_lval.cstr,verilogscannerYYtext,verilogscannerYYleng);c_lval.cstr[verilogscannerYYleng]='\0';return END_TOK;}REJECT;}
<Start>"begin" {if(check(false)) return BEGIN_TOK; REJECT;}
<Start>"fork" {if(check(false)) return FORK_TOK; REJECT;}
<Start>"generate" { if(check()) return GENERATE_TOK;REJECT;}
<Start>"endgenerate" { if(check()) return ENDGENERATE_TOK;REJECT;}
<Start>"genvar" { if(check()) return GENVAR_TOK;REJECT;}
<Start>"default" { if(check()) return DEFAULT_TOK;REJECT;}
<Start>"automatic" { if(check()){ addText(verilogscannerYYtext,verilogscannerYYleng); return AUTO_TOK;}REJECT;}
<Start>"signed" { if(check()){ yyPrevLine=yyLineNr; addText(verilogscannerYYtext,verilogscannerYYleng); return SIGNED_TOK;}REJECT;}
<Start>"default" { if(check()) return DEFAULT_TOK;REJECT;}
<Start>"endcase" { if(check()) return ENDCASE_TOK;REJECT;}
<Start>"else" { if(check()) return ELSE_TOK; REJECT;}
<Start>"while" { if(check()) return WHILE_TOK; REJECT;}
<Start>"repeat" { if(check()) return REPEAT_TOK;REJECT;}
<Start>"forever" { if(check()) return FOREVER_TOK;REJECT;}
<Start>"casez" { if(check()) return CASEZ_TOK; REJECT;}
<Start>"casex" { if(check()) return CASEX_TOK;REJECT;}
<Start>"case" { if(check()) return CASE_TOK;REJECT;}
<Start>"if" { if(check()) return IF_TOK;REJECT;}
<Start>"disable" { if(check()) return DISABLE_TOK;REJECT;}
<Start>"deassign" { if(check()) return DEASSIGN_TOK;REJECT;}
<Start>"release" { if(check()) return RELEASE_TOK; REJECT;}
<Start>"force" { if(check()) return FORCE_TOK; REJECT; }
<Start>"wait" { if(check()) return WAIT_TOK; REJECT;}
<Start>"join" { if(check()) return JOIN_TOK; REJECT;}
<Start>"for" { if(check()) return FOR_TOK; REJECT;}
<Start>"always" { if(check()) { yyPrevLine=yyLineNr; return ALWAYS_TOK;}REJECT;}
<Start>"endfunction" { if(check()){yyPrevLine=yyLineNr; return ENDFUNC_TOK;} REJECT;}
<Start>"function" { if(check()){yyPrevLine=yyLineNr; return FUNC_TOK;} REJECT;}
<Start>"endtask" { if(check()){yyPrevLine=yyLineNr; return ENDTASK_TOK;}REJECT;}
<Start>"task" { if(check()){yyPrevLine=yyLineNr; return TASK_TOK;} REJECT;}
<Start>"table" { if(check()) return TABLE_TOK; REJECT;}
<Start>"endtable" { if(check()) return ENDTABLE_TOK; REJECT;}
<Start>"initial" { if(check()) {return INITIAL_TOK;} REJECT;}
<Start>"endprimitive" { if(check()) return ENDPRIMITIVE_TOK;REJECT;}
<Start>"primitive" { if(check()){yyPrevLine=yyLineNr; return PRIMITIVE_TOK;} REJECT;}
<Start>"macromodule" { if(check()) return MACRO_MODUL_TOK; REJECT;}
<Start>"module" { if(check()) { yyPrevLine=yyLineNr;return MODUL_TOK; } REJECT;}
<Start>"endmodule" {
if(check())
{
// yyEndModLine=yyLineNr+yyEndModLine1;
return ENDMODUL_TOK;
}REJECT;
}
<Start>"reg" { if(check()) {yyPrevLine=yyLineNr; addText(verilogscannerYYtext,verilogscannerYYleng);return REG_TOK; } REJECT;}
<Start>"integer" { if(check()) {yyPrevLine=yyLineNr; addText(verilogscannerYYtext,verilogscannerYYleng);return INTEGER_TOK;}REJECT;}
<Start>"defparam" { if(check()) return DEFPARAM_TOK; REJECT;}
<Start>"real" { if(check()) {yyPrevLine=yyLineNr; addText(verilogscannerYYtext,verilogscannerYYleng); return REAL_TOK; } REJECT; }
<Start>"event" { if(check()){yyPrevLine=yyLineNr;addText(verilogscannerYYtext,verilogscannerYYleng); return EVENT_TOK;}REJECT;}
<Start>"assign" { if(check()) return ASSIGN_TOK; REJECT;}
<Start>"scalared" { if(check()) return SCALAR_TOK;REJECT;}
<Start>"vectored" { if(check()) return VEC_TOK; REJECT;}
<Start>"small" { if(check()) return SMALL_TOK;REJECT;}
<Start>"medium" { if(check()) return MEDIUM_TOK; REJECT;}
<Start>"large" { if(check()) return LARGE_TOK; REJECT;}
<Start>"output" { if(check()) {yyPrevLine=yyLineNr; addText(verilogscannerYYtext,verilogscannerYYleng); return OUTPUT_TOK; }REJECT;}
<Start>"input" { if(check()) {yyPrevLine=yyLineNr; addText(verilogscannerYYtext,verilogscannerYYleng); return INPUT_TOK;} REJECT;}
<Start>"inout" { if(check()) {yyPrevLine=yyLineNr; addText(verilogscannerYYtext,verilogscannerYYleng); return INOUT_TOK; }REJECT;}
<Start>"parameter" { if(check()) {yyPrevLine=yyLineNr;return PARAMETER_TOK;}REJECT;}
<Start>"localparam" { if(check()) {yyPrevLine=yyLineNr; return LOCALPARAM_TOK;}REJECT;}
<Start>{NETTYPE} { if(check()) { yyPrevLine=yyLineNr; addText(verilogscannerYYtext,verilogscannerYYleng);return NET_TOK;} REJECT;}
<Start>{STRENGTH0} { if(check()) { addText(verilogscannerYYtext,verilogscannerYYleng); return STR0_TOK;} REJECT;}
<Start>{STRENGTH1} { if(check()) { addText(verilogscannerYYtext,verilogscannerYYleng); return STR1_TOK;}REJECT;}
<Start>{GATETYPE} { if(check()) { addText(verilogscannerYYtext,verilogscannerYYleng); return GATE_TOK;}REJECT;}
<*>B*"//%"[^{}\n][^\n]*\n/{LL}*"//%" { // found multiline comment
QCString text(verilogscannerYYtext);
if(!g_parseCode){
if(iDocLine==-1){
iDocLine=yyLineNr;
}
// Entry* pTemp=VerilogDocGen::getEntryAtLine(curRoots,iDocLine);
/*
if (pTemp)
{ // found one line comment, add it to the entry on this line
pTemp->briefLine=yyLineNr;
pTemp->brief+=yytext;
VhdlDocGen::prepareComment(pTemp->brief);
}
else
*/
if(!checkMultiComment(text))
{
strComment+=verilogscannerYYtext;
multLineComment=true;
}
yyLineNr+=text.contains('\n');
}
if(g_parseCode) {
if(Config_getBool("STRIP_CODE_COMMENTS"))
qlist.append(new QCString(verilogscannerYYtext));
else{
QStringList ql=QStringList::split('\n',text,false);
//QCString trial=(QCString)ql[0];
qlist.append(new QCString(ql[0].data()));
qlist.append(new QCString("\n"));
if(ql.count()>1)
qlist.append(new QCString(ql[1].data()));
}
}
c_lval.ctype=' ';
BEGIN(tagComment);
}
<tagComment>B*"//%"[^\n]* {
if (iDocLine==-1) iDocLine=yyLineNr;
if(!g_parseCode){
strComment+=verilogscannerYYtext;
int index =strComment.find("\\code");
if(index>0)
{
startCodeBlock(index);
}
}
//fprintf(stderr,"[[ \n %s ]]",strComment.data());
if(g_parseCode)
{
qlist.append(new QCString(verilogscannerYYtext));
}
BEGIN(tagComment);
}
<tagComment>.|\n {
// found end of comment block
int index =strComment.find("\\code");
// fprintf(stderr," %s ",strComment.data());
// assert(false);
if(!g_parseCode && index>0)
{
startCodeBlock(index);
/*
int ll=strComment.length();
iCodeLen=inputVerilogString.findRev(strComment.data(),num_chars)+ll;
// fprintf(stderr,"\n startin code..%d %d %d\n",iCodeLen,num_chars,ll);
gBlock.reset();
int len=strComment.length();
QCString name=strComment.right(len-index);//
name=VhdlDocGen::getIndexWord(name.data(),1);
if(!name)
gBlock.name="misc"+ VhdlDocGen::getRecordNumber();
else
gBlock.name=name;
strComment=strComment.left(index);
gBlock.startLine=yyLineNr+1;
gBlock.bodyLine=yyLineNr+1;
VhdlDocGen::prepareComment(strComment);
gBlock.brief+=strComment;
*/
}
else if(!g_parseCode)
{
strComment+=verilogscannerYYtext;
VhdlDocGen::prepareComment(strComment);
handleVerilogCommentBlock(strComment,FALSE,iDocLine);
unput(*verilogscannerYYtext);
}
if(g_parseCode) // && !Config_getBool("STRIP_CODE_COMMENTS"))
{
qlist.append(new QCString(verilogscannerYYtext));
}
strComment.resize(0);
BEGIN(Start);
}
<*>"//%"[^\n]* { // one line comment
if (iDocLine==-1) iDocLine=yyLineNr;
QCString qcs(verilogscannerYYtext);
bool isEndCode=qcs.contains("\\endcode");
int index = qcs.find("\\code");
if(isEndCode && !g_parseCode)
{
// fprintf(stderr,"\n ending code..");
int end=inputVerilogString.find(qcs.data(),iCodeLen);
makeInlineDoc(end);
}
else if(index > 0 && !g_parseCode) {
// assert(false);
strComment=qcs;
startCodeBlock(index);
strComment.resize(0);
}
else if(!g_parseCode)
{
VhdlDocGen::prepareComment(qcs);
//printf("--> handleCommentBlock line %d\n",yyLineNr);
if(!checkMultiComment(qcs))
{
handleVerilogCommentBlock(qcs,TRUE,iDocLine);
}
}//if
if(g_parseCode) // && !Config_getBool("STRIP_CODE_COMMENTS"))
{
qlist.append(new QCString(verilogscannerYYtext));
}
}
<Start>{COMMENT} {
QCString text(verilogscannerYYtext);
//fprintf(stderr,"\n %s",text.data());
int b=text.contains(vlogComment);
if(b && !g_parseCode){
strComment+=verilogscannerYYtext;
if (iDocLine==-1) iDocLine=yyLineNr;
VhdlDocGen::prepareComment(strComment);
if(multLineComment){
handleVerilogCommentBlock(strComment,FALSE,iDocLine);
multLineComment=false;
}
else{
if(!checkMultiComment(text))
handleVerilogCommentBlock(strComment,true,iDocLine);
}//else
}
strComment.resize(0);
if(g_parseCode)
{
qlist.append(new QCString(verilogscannerYYtext));
}
c_lval.ctype=verilogscannerYYtext[0];
}
<Start>{STRING} {
// fprintf(stderr,"\n [%s : %c %d] string\n",verilogscannerYYtext,verilogscannerYYtext[verilogscannerYYleng-2],verilogscannerYYleng);
if((verilogscannerYYleng > 2) && verilogscannerYYtext[verilogscannerYYleng-2] != 92) {
addText(verilogscannerYYtext,verilogscannerYYleng);
if(g_parseCode) { qlist.append(new QCString(verilogscannerYYtext));c_lval.ctype=verilogscannerYYtext[0];}
return STRING_TOK;
}
if(verilogscannerYYleng == 2){
if(g_parseCode) { qlist.append(new QCString(verilogscannerYYtext)); }
return STRING_TOK;
}
unput(verilogscannerYYtext[verilogscannerYYleng-1]);
yymore();
}
<Start>"\t"|"\r" {
if(yytext[0]=='\t'){
if(!g_parseCode)
parseToken(" ");
else
parseToken(verilogscannerYYtext);
}
c_lval.ctype=' ';}
<Start,EndOfText>[\n] {
// fprintf(stderr,"\nparse code line: [line: %d]",yyLineNr);
addToken('\n');
if(g_parseCode){
yyEndModLine++;
// yyEndModLine1=QCString(verilogscannerYYtext).contains('\n');
qlist.append(new QCString(verilogscannerYYtext));
}
else
yyLineNr+=QCString(verilogscannerYYtext).contains('\n');
c_lval.ctype=verilogscannerYYtext[0];
}
<Start>[ ]+ { parseToken(verilogscannerYYtext);}
<Start>[0-9]+|[0-9][0-9_]+|[0-9]+{BASE}[0-9a-zA-Z_?]*|[0-9]+"."[0-9eE]+|{BASE}[0-9a-zA-Z_?]*|['][01xz] {
addText(verilogscannerYYtext,verilogscannerYYleng);
if(verilogscannerYYleng>(VBUF_SIZE-1))
verilogscannerYYleng=VBUF_SIZE;
strncpy(c_lval.cstr,verilogscannerYYtext,verilogscannerYYleng);
c_lval.cstr[verilogscannerYYleng]='\0';
if(g_parseCode) qlist.append(new QCString(verilogscannerYYtext));
return DIGIT_TOK;
}
<Start>[a-zA-Z]+|[_a-zA-Z$][_a-zA-Z0-9$]+ {
addText(verilogscannerYYtext,verilogscannerYYleng);
if(g_parseCode){
qlist.append(new QCString(verilogscannerYYtext));
}
if(verilogscannerYYleng>(VBUF_SIZE-1))
verilogscannerYYleng=VBUF_SIZE;
strncpy(c_lval.cstr,verilogscannerYYtext,verilogscannerYYleng);
c_lloc.last_line= c_lloc.first_line;
c_lval.cstr[verilogscannerYYleng]='\0';
// c_lloc.last_line= c_lloc.first_line;
c_lloc.first_line=yyLineNr;
return LETTER_TOK;
}
<Start>. {
c_lval.ctype=verilogscannerYYtext[0];
if(c_lval.ctype=='`')
unput('`');
REJECT;
}
<Start>"(*" { parseToken(verilogscannerYYtext); return ATL_TOK;}
<Start>"*)" { parseToken(verilogscannerYYtext); return ATR_TOK;}
<Start>"~^" { parseToken(verilogscannerYYtext); return SNNOT_TOK;}
<Start>"^~" { parseToken(verilogscannerYYtext); return NOTSN_TOK;}
<Start>"&&&" { parseToken(verilogscannerYYtext); return AAAND_TOK;}
<Start>"&&" { parseToken(verilogscannerYYtext); return AAND_TOK;}
<Start>"||" { parseToken(verilogscannerYYtext); return OOR_TOK;}
<Start>"!" { parseToken(verilogscannerYYtext); return EXCLAMATION_TOK;}
<Start>"_" { parseToken(verilogscannerYYtext); return UNDERSCORE_TOK;}
<Start>";" { parseToken(verilogscannerYYtext); return SEM_TOK;}
<Start>"." { parseToken(verilogscannerYYtext); return DOT_TOK;}
<Start>"," { parseToken(verilogscannerYYtext); return COMMA_TOK;}
<Start>"?" { parseToken(verilogscannerYYtext);return QUESTION_TOK;}
<Start>"+" { parseToken(verilogscannerYYtext);return PLUS_TOK;}
<Start>"-" { parseToken(verilogscannerYYtext);return MINUS_TOK;}
<Start>":" { parseToken(verilogscannerYYtext); return COLON_TOK;}
<Start>"(" { parseToken(verilogscannerYYtext);if(g_parseCode) { c_lval.cstr[0]=' ';} return LBRACE_TOK;}
<Start>")" { parseToken(verilogscannerYYtext);return RBRACE_TOK;}
<Start>"}" { parseToken(verilogscannerYYtext);return RRAM_TOK;}
<Start>"{" { parseToken(verilogscannerYYtext);return LRAM_TOK;}
<Start>"[" { parseToken(verilogscannerYYtext);return LBRACKET_TOK;}
<Start>"]" { parseToken(verilogscannerYYtext);return RBRACKET_TOK;}
<Start>"&" { parseToken(verilogscannerYYtext);return AND_TOK;}
<Start>"|" { parseToken(verilogscannerYYtext); return OR_TOK;}
<Start>"=" { parseToken(verilogscannerYYtext); return EQU_TOK;}
<Start>"<" { parseToken(verilogscannerYYtext); return GT_TOK;}
<Start>">" { parseToken(verilogscannerYYtext);return LT_TOK;}
<Start>"^" { parseToken(verilogscannerYYtext);return NOT_TOK;}
<Start>"~" { parseToken(verilogscannerYYtext); return SN_TOK;}
<Start>"*" { parseToken(verilogscannerYYtext);return MULT_TOK;}
<Start>"%" { parseToken(verilogscannerYYtext);return PERCENTAL_TOK;}
<Start>"@" { parseToken(verilogscannerYYtext);return AT_TOK;}
<Start>"#" { parseToken(verilogscannerYYtext); return PARA_TOK;}
<Start>"$" { if(g_parseCode) parseToken(verilogscannerYYtext); return DOLLAR_TOK;}
<Start>"/*" {
vbufreset();
addText(verilogscannerYYtext,verilogscannerYYleng);
if(yy_hold_char=='!') // found comment starting with "/*!"
doxComment=true;
startComment=yyLineNr;
BEGIN(StartComment);
}
<Start>"/" {
char c=yy_hold_char;
if(c !='/'){
parseToken(verilogscannerYYtext);
return ENV_TOK;
}
unput('/');// found "//"
REJECT;}
<StartComment>[^*]*[*]+ {
QCString tt(verilogscannerYYtext);
int len=tt.length();
if(verilogscannerYYtext[len-1]=='*' && tt.contains('\n'))
{
QCString ss=tt;
VhdlDocGen::deleteAllChars(ss,' ');
VhdlDocGen::deleteAllChars(ss,'\t');
if(ss.data() && ss.at(ss.length()-2)=='\n')
{
tt=tt.left(len-1);
len--;
}
}
addText(tt.data(),len);
char c=yy_hold_char;
if(c =='/'){
unput('*');
BEGIN(Commentt);
}
else BEGIN(StartComment);
}
<Commentt>"*/" {
QCString *qq=new QCString(getVerilogString());
qq->append("*/");
if(g_parseCode){
qlist.append(qq);
}
else{
if(doxComment){
qq->stripPrefix("/*!");
*qq=qq->left(qq->length()-2);
handleVerilogCommentBlock(*qq,FALSE,startComment);
}
yyLineNr+=qq->contains('\n');
doxComment=false;
delete qq;
}
vbufreset();
BEGIN(Start);
}
%%
//------ -------------------------------------------------------------------------------------------------
// do parsing
int MyParserConv::doLex(){
int token;
token=yylex();
// fprintf(stderr,"\ntoken: %d",token);
return token;
}
void resetScanner(const char* s,MyParserConv* parse) { }
void vbufreset()
{
int i;
i=getVerilogToken();
memset(&g_buf[0],'\0',iSize);
iSize=0;
if(i==LETTER_TOK){
lastLetter=verilogscannerYYtext;
}
}
void addToken (char c)
{
if(iSize>inputPosition)
{
vbufreset();
// assert(0);
}
g_buf[iSize]=c;
iSize++;
g_buf[iSize]='\0';
}
QCString getLastLetter(){ return lastLetter; }
void addText (char *word, int len)
{
while(len-->0)
g_buf[iSize++]=*word++;
g_buf[iSize]='\0';
}
const char* getVerilogString() {if(iSize) return &g_buf[0];return NULL;}
const char* getVerilogParsingFile(){return yyFileName.data();}
int getVerilogLine() { return yyLineNr; }
int getVerilogPrevLine() { return yyPrevLine; }
int getVerilogEndLine(){ return yyEndLine; };
int getVerilogEndModuleLine()
{
return yyEndModLine;
};
void VerilogScanner::resetCodeParserState(){}
bool VerilogScanner::needsPreprocessing(const QCString &extension){ return true; }
void VerilogScanner::parsePrototype(const char *text){ }
void VerilogScanner::parseInput(const char *fileName,const char *fileBuf,Entry *root,
bool /*sameTranslationUnit*/,
QStrList & /*filesInSameTranslationUnit*/)
{
yyFileName= QCString(fileName);
fprintf(stderr," \n parse Verilog File: %s \n",yyFileName.data());
//verilogscannerYY_flex_debug=1;
bool xilinx_ucf=isConstraintFile(yyFileName,".ucf");
bool altera_qsf=isConstraintFile(yyFileName,".qsf");
// support XILINX(ucf) and ALTERA (qsf) file
// printf("%s",fileBuf);
if(xilinx_ucf) { VhdlDocGen::parseUCF(fileBuf,root,yyFileName,false); return; }
if(altera_qsf) { VhdlDocGen::parseUCF(fileBuf,root,yyFileName,true); return; }
num_chars=0;
QCString pPuffer(" ");
pPuffer+=fileBuf;
if(!g_lexInit)
buildKeyMap();
inputFile.setName(fileName);
if(g_lexInit)
verilogscannerYYrestart( verilogscannerYYin );
g_lexInit=TRUE;
curRoots=root;
initVerilogParser(curRoots,false);
g_thisParser=this;
iSize=0;
int len =inputFile.size();
inputPosition=0;
g_buf=new char[len+1024];
assert(g_buf);
inputVerilogString=pPuffer.data();
g_inputLines = countLines();
totLines=g_inputLines;
yyLineNr=1;
pconv=new MyParserConv();
resetScanner(NULL,pconv);
groupEnterFile(fileName,yyLineNr);
int ok=pconv->parse(pconv);
// globalMemberList.clear();
qlist.clear();
delete [] g_buf;g_buf=0;
delete pconv;
}
static void parseConstraint(const QCString & input)
{
QStringList qsl=QStringList::split("\n",input);
codifyLines(input.data());
/*
for(uint j=0;j<qsl.count();j++)
{
QCString q=(QCString)qsl[j];
writeVWord(QCString& qcs)
}
*/
}// parseConstraint
void VerilogScanner::parseCode(CodeOutputInterface &codeOutIntf,
const char *scopeName,
const QCString &input,
SrcLangExt /*lang*/,
bool isExampleBlock,
const char *exampleName,
FileDef *fileDef,
int startLine,
int endLine,
bool inlineFragment,
MemberDef *memberDef,
bool showLineNumbers,
Definition *searchCtx,
bool
)
{
num_chars=0;
TooltipManager::instance()->clearTooltips();
// Definition *di=(Definition*)fileDef;
QCString pPuffer(" ",1);
if(!fileDef)
{
fprintf(stderr," spe code << %s >> \n",input.data());
return;
}
assert(fileDef);
yyFileName=fileDef->fileName();
g_code = &codeOutIntf;
fprintf(stderr," \n %s \n",yyFileName.data());
QCString ff(yyFileName);
if (Config_getBool("ENABLE_PREPROCESSING") && startLine==-1)
{
VerilogPreProc defProc;
defProc.lineDirectives(false);
QFileInfo fi(fileDef->absFilePath());
pPuffer=defProc.performPreprocessing(fi).data();
// cerr<<pPuffer.data();
// if(ff.data())
// fprintf(stderr,"\nPreprocessing code of file %s...\n",ff.data());
}
else
pPuffer+=input.data();
// printf("%s",pPuffer.data());
initVerilogParser(0,true);
VerilogDocGen::buildGlobalVerilogVariableDict(fileDef,true);
if(memberDef)// write code for function body
{
ClassDef *dd=memberDef->getClassDef();
if(dd)
g_CurrClass=dd->className();
VerilogDocGen::setCurrVerilogClass(g_CurrClass);
startLine--;
}
inputVerilogString = pPuffer.data();
inputPosition = 0;
iSize=0;
g_buf=new char[input.length()+1024];
assert(g_buf);
g_currentFontClass = 0;
g_needsTermination = FALSE;
if (endLine!=-1)
g_inputLines = endLine+1;
else
g_inputLines = countLines();
totLines=g_inputLines;
if (startLine!=-1)
yyLineNr = startLine;
else
yyLineNr = 1;
g_exampleName = exampleName;
g_sourceFileDef = fileDef;
if (isExampleBlock && fileDef==0)
{
// create a dummy filedef for the example
g_sourceFileDef = new FileDef("",exampleName);
}
g_searchCtx = searchCtx;
if (g_sourceFileDef)
{
QCString qcs("100001");
setCurrentDoc(qcs);
}
g_currentDefinition = 0;
g_currentMemberDef = 0;
if (!g_exampleName.isEmpty())
{
g_exampleFile = convertNameToFile(g_exampleName+"-example");
}
g_includeCodeFragment = inlineFragment;
if(!memberDef) startCodeLine();
bool xilinx_ucf=isConstraintFile(yyFileName,".ucf");
bool altera_qsf=isConstraintFile(yyFileName,".qsf");
if(xilinx_ucf || altera_qsf)
{
parseConstraint(input);
return;
}
verilogscannerYYrestart( verilogscannerYYin );
g_parseCode=true;
MyParserConv conv;
resetScanner(input.data(),&conv);
int ok=conv.parse(&conv);
if (isExampleBlock && g_sourceFileDef)
{
// delete the temporary file definition used for this example
delete g_sourceFileDef;
g_sourceFileDef=0;
}
printVerilogBuffer(true);
if (fileDef)
{
TooltipManager::instance()->writeTooltips(*g_code);
}
// globalMemberList.clear();
g_parseCode=false;
delete [] g_buf;g_buf=0;
return;
}
//-------------------------------------------------------------------------------------------------------
// parse 'include /'define
static void parseGlobalMember(){
QCString tmp,args,name,comment;
QCString qcs(getVerilogString());
bool bInc=qcs.contains("`include");
if(qcs.stripPrefix("`define") || qcs.stripPrefix("`include"))
{
comment=checkComment(qcs);
if(!comment.stripPrefix("//%"))
comment.resize(0);
QRegExp reg("[^a-zA-Z_0-9$]+");
qcs=qcs.stripWhiteSpace();
int ll=qcs.find(reg,0);
if(ll>0){
args=qcs.mid(ll,qcs.length());
name=qcs.left(ll);
}
if(ll==-1)
{
int len;
QRegExp reg("[[a-zA-Z_][a-zA-Z_0-9$]+");
int ll=reg.match(qcs,0,&len);
int strlen=qcs.length();
if(strlen==len)
name=qcs;
}
if(!comment.isEmpty())
handleVerilogCommentBlock(comment,true,yyLineNr);
if(bInc)
{
VhdlDocGen::deleteAllChars(qcs,'"');
qcs.simplifyWhiteSpace();
if(qcs.isEmpty())return;
qcs=VerilogDocGen::getFileNameFromString(qcs.data());
Entry* pTemp=VerilogDocGen::makeNewEntry(qcs.data(),Entry::VARIABLE_SEC,VerilogDocGen::INCLUDE,yyLineNr,true);
pTemp->type="include";
return;
}
// VhdlDocGen::deleteAllChars(args,'\\');
Entry* op=getCurrVerilog();
bool bGlobal=op;
Entry* pTemp=VerilogDocGen::makeNewEntry(name.data(),Entry::VARIABLE_SEC,VerilogDocGen::FEATURE,defineLineContinue,bGlobal);
pTemp->args=args;
pTemp->type="feature";
// if(getCurrVerilog()!=0) return; // found definition outside a module(not global)
if(!bGlobal){
Entry *pNew=new Entry(*pTemp);
globalMemberList.insert(pNew->name,pNew);
}
}
}// parseGlobalMember
bool handleVerilogCommentBlock(const QCString &doc,bool brief,int iDoc)
{
int position=0;
bool needsEntry=FALSE;
if(g_parseCode) return 0;
Entry* curr=getCurrVerilogEntry();
if(curr==NULL){
assert(0);
curr=new Entry();
curRoots->addSubEntry(curr);
}
Protection protection=Public;
if (brief)
curr->briefLine = iDoc;
else
curr->docLine = iDoc;
// printf("parseCommentBlock %p [%s]\n",curr,doc.data());
while(parseCommentBlock(
g_thisParser,
curr,
doc, // text
yyFileName, // file
iDocLine, // line of block start
brief,
false,
FALSE,
protection,
position,
needsEntry
)){
if (needsEntry)
{
// fprintf(stderr,"\n<<need new entry in while%s>>",doc.data());
VerilogDocGen::makeNewEntry(curr->name.data(),curr->section,curr->spec,0,true);
}
}
if (needsEntry)
{
//fprintf(stderr,"\n<<need new entry %s>>",doc.data());
VerilogDocGen::makeNewEntry(curr->name.data(),curr->section,curr->spec,0,true);
}
iDocLine=-1;
return false;
}
// returns the stored member in the global list
// file : member file
MemberDef* findGlobalMember(const QCString & file, const QCString& memName){
MemberDef *md;
bool ambig;
FileDef *fd=findFileDef(Doxygen::inputNameDict,file,ambig);
if(!fd) return NULL;
MemberList * ml=fd->getMemberList(MemberListType_allMembersList);
if(ml==NULL) return NULL;
MemberListIterator fmni(*ml);
for (fmni.toFirst();(md=fmni.current());++fmni)
{
if(md->getMemberSpecifiers()==0 || md->getMemberSpecifiers()==VerilogDocGen::FEATURE ){
if(strcmp(md->name().data(),memName.data())==0) return md;
}
}//for
return NULL;
}//findDefinition
MemberDef* findGlobalMember(const QCString& memName){
QCString temp=memName;
temp.stripPrefix("`");
Entry* ee=globalMemberList.find(temp.data());
if(ee){
QCString file=VerilogDocGen::getFileNameFromString(ee->fileName.data());
return findGlobalMember(file,temp);
}
return NULL;
}
void parseLib(char *str)
{
QRegExp ep("[\t ]");
QCString temp=str;
temp.stripPrefix("library");
QCString lib=temp.simplifyWhiteSpace();
if(!g_parseCode)
{
yyLineNr+=temp.contains('\n');
int i=lib.find(ep);
assert(i>0);
Entry* pTemp=VerilogDocGen::makeNewEntry(lib.left(i).data(),Entry::VARIABLE_SEC,VerilogDocGen::LIBRARY,yyLineNr);
pTemp->type="library";
Entry *pNew=new Entry(*pTemp);
globalMemberList.insert(pNew->name,pNew);
}
else
{
// qlist.append(new QCString(verilogscannerYYtext));
printVerilogBuffer(true);
writeFont("vhdlkeyword","library");
codifyLines(temp.data());
}
}//parseLib
QCString checkComment(QCString& q)
{
QCString comment;
int j=q.find("//");
if(j>0){
comment=q.right(q.length()-j);
q=q.left(j);
return comment;
}
int k=q.find("/*");
int l=q.find("*/");
if((k>0) &&(l>k) )
{
comment=q.right(q.length()-k);
q=q.left(k);
}
return comment;
}
void composeString(QCString& q)
{
QRegExp ep("[`a-zA-Z0-9_'?]+");
QRegExp ep2("[\\s]+");
// j = reg.match(temp.data(),0,&len);
int index=q.find("");
if(index>-1)
q=q.remove(index,1);
int len;
int j=ep.match(q.data(),0,&len );
while(j>=0){
QCString left=q.left(len);
qlist.append(new QCString(left.data()));
q=q.right(q.length()-len);
j=ep2.match(q.data(),0,&len);
if(j>=0)
{
left=q.left(len);
qlist.append(new QCString(left.data()));
q=q.right(q.length()-len);
}
j=ep.match(q.data(),0,&len);
if(j>0)
len=1;
}
if(!q.isEmpty())
qlist.append(new QCString(q.data()));
}
static void writeInclude(QCString inc)
{
if(inc.isEmpty()) return;
int i=inc.find("\"");
int j=inc.findRev("\"");
if(i>=0 && j>i)
{
QCString first=inc.left(i+1);
QCString third=inc.right(inc.length()-j);
QCString mid=inc.mid(i+1,j-i-1);
QCString ff=VerilogDocGen::getFileNameFromString(mid.data());
bool ambig;
FileDef *fd=findFileDef(Doxygen::inputNameDict,ff,ambig);
if(fd)
{
g_code->codify(first.data());
g_code->writeCodeLink(fd->getReference(),
fd->getOutputFileBase(),
fd->fileName(),
mid.data(),0
);
g_code->codify(third.data());
}
else
writeWord(inc.data());
}
}
......@@ -190,8 +190,8 @@ static void startCodeLine()
//QCString lineNumber,lineAnchor;
//lineNumber.sprintf("%05d",g_yyLineNr);
//lineAnchor.sprintf("l%05d",g_yyLineNr);
// if ((g_yyLineNr % 500) == 0)
// fprintf(stderr,"\n starting Line %d:",g_yyLineNr);
// if ((g_yyLineNr % 50) == 0)
// fprintf(stderr,"\n starting Line %d:",g_yyLineNr);
Definition *d = g_sourceFileDef->getSourceDefinition(g_yyLineNr);
//printf("startCodeLine %d d=%s\n", g_yyLineNr,d ? d->name().data() : "<null>");
if (!g_includeCodeFragment && d)
......
......@@ -27,7 +27,7 @@
#include <qcstring.h>
#include <qfileinfo.h>
#include <qstringlist.h>
#include "definition.h"
//#ifdef DEBUGFLOW
#include <qmap.h>
//#endif
......@@ -64,6 +64,10 @@
#include "VhdlParser.h"
#include "vhdlcode.h"
#include "verilogdocgen.h"
#include "verilogscanner.h"
#define theTranslator_vhdlType VhdlDocGen::trVhdlType
static QDict<QCString> g_vhdlKeyDict0(17,FALSE);
......@@ -73,7 +77,7 @@ static QDict<QCString> g_vhdlKeyDict3(17,FALSE);
static QDict<QCString> g_xilinxUcfDict(17,FALSE);
static void initUCF(Entry* root,const char* type,QCString & qcs,int line,QCString & fileName,QCString & brief);
static void writeUCFLink(const MemberDef* mdef,OutputList &ol);
static void assignBinding(VhdlConfNode* conf);
static void addInstance(ClassDef* entity, ClassDef* arch, ClassDef *inst,Entry *cur,ClassDef* archBind=NULL);
......@@ -140,7 +144,7 @@ static void writeLink(const MemberDef* mdef,OutputList &ol)
mdef->name());
}
static void startFonts(const QCString& q, const char *keyword,OutputList& ol)
void VhdlDocGen::startFonts(const QCString& q, const char *keyword,OutputList& ol)
{
ol.startFontClass(keyword);
ol.docify(q.data());
......@@ -799,13 +803,12 @@ MemberDef* VhdlDocGen::findMember(const QCString& className, const QCString& mem
ecd=cd;
if (!packages.contains(ecd)) VhdlDocGen::findAllPackages(ecd);
}
uint len=packages.count();
for (uint j=0;j<len;j++)
{
for (QMap<ClassDef*,QList<ClassDef> >::Iterator cList=packages.begin();cList != packages.end();cList++)
{
if (cList.key()==0) continue;
QMap<ClassDef*,QList<ClassDef> >::Iterator cList=packages.find(ecd);
if(cList.key()!=0)
{
QList<ClassDef> mlist=cList.data();
for (uint j=0;j<mlist.count();j++)
{
......@@ -814,8 +817,8 @@ MemberDef* VhdlDocGen::findMember(const QCString& className, const QCString& mem
mdef=VhdlDocGen::findMemberDef(mlist.at(j),memName,MemberListType_pubMethods);
if (mdef) return mdef;
}
}
}
}
return 0;
}//findMember
......@@ -885,9 +888,9 @@ void VhdlDocGen::findAllPackages( ClassDef *cdef)
if (packages.contains(cdef)) return;
MemberList *mem=cdef->getMemberList(MemberListType_variableMembers);
MemberDef *md;
if (!mem) return;
// printf("\n search package in entity %s .. ",cdef->name().data());
MemberListIterator fmni(*mem);
for (fmni.toFirst();(md=fmni.current());++fmni)
{
......@@ -898,7 +901,8 @@ void VhdlDocGen::findAllPackages( ClassDef *cdef)
{
cList.append(cd);
VhdlDocGen::findAllPackages(cd);
packages.insert(cdef,cList);
// printf("\n insert in entity %s packages %d..",cdef->name().data(),cList.count());
packages.insert(cdef,cList);
}
}
}//for
......@@ -976,6 +980,12 @@ QCString VhdlDocGen::getClassTitle(const ClassDef *cd)
{
QCString pageTitle;
if (cd==0) return "";
static bool optVerilog = Config_getBool("OPTIMIZE_OUTPUT_VERILOG");
if(optVerilog)
return VerilogDocGen::getClassTitle(cd);
pageTitle+=cd->displayName();
pageTitle=VhdlDocGen::getClassName(cd);
int ii=cd->protection();
......@@ -1151,8 +1161,14 @@ void VhdlDocGen::writeVhdlLink(const ClassDef* ccd ,OutputList& ol,QCString& typ
*/
void VhdlDocGen::prepareComment(QCString& qcs)
{
static bool optVerilog = Config_getBool("OPTIMIZE_OUTPUT_VERILOG");
const char* s="--!";
int index=0;
if(optVerilog)
s=vlogComment;
else
s="--!";
while (TRUE)
{
......@@ -1244,7 +1260,15 @@ QCString VhdlDocGen::getIndexWord(const char* c,int index)
QCString VhdlDocGen::getProtectionName(int prot)
{
if (prot==VhdlDocGen::ENTITYCLASS)
static bool optVerilog = Config_getBool("OPTIMIZE_OUTPUT_VERILOG");
if(optVerilog)
{
if(prot==Public) return "Module";
return "Primitive";
}
if (prot==VhdlDocGen::ENTITYCLASS)
return "entity";
else if (prot==VhdlDocGen::ARCHITECTURECLASS)
return "architecture";
......@@ -1258,7 +1282,13 @@ QCString VhdlDocGen::getProtectionName(int prot)
QCString VhdlDocGen::trTypeString(uint64 type)
{
switch(type)
static bool optVerilog = Config_getBool("OPTIMIZE_OUTPUT_VERILOG");
if(optVerilog)
return VerilogDocGen::convertTypeToString(type);
switch(type)
{
case VhdlDocGen::LIBRARY: return "Library";
case VhdlDocGen::ENTITY: return "Entity";
......@@ -1341,8 +1371,17 @@ QCString VhdlDocGen::getRecordNumber()
QCString VhdlDocGen::getProcessNumber()
{
static int stringCounter;
static bool optVerilog=Config_getBool("OPTIMIZE_OUTPUT_VERILOG");
char buf[8];
QCString qcs("PROCESS_");
QCString qcs;
if(optVerilog)
qcs="ALWAYS_";
else
qcs="PROCESS_";
sprintf(buf,"%d",stringCounter++);
qcs.append(&buf[0]);
return qcs;
......@@ -1354,15 +1393,17 @@ QCString VhdlDocGen::getProcessNumber()
void VhdlDocGen::writeFormatString(const QCString& s,OutputList&ol,const MemberDef* mdef)
{
QRegExp reg("[\\[\\]\\.\\/\\:\\<\\>\\:\\s\\,\\;\\'\\+\\-\\*\\|\\&\\=\\(\\)\"]");
static bool optVerilog=Config_getBool("OPTIMIZE_OUTPUT_VERILOG");
const int COL_SIZE=80;
QRegExp reg("[\\[\\]\\.\\/\\:\\<\\>\\:\\s\\,\\;\\'\\+\\-\\*\\|\\&\\=\\(\\)\"]");
QCString qcs = s;
qcs+=QCString(" ");// parsing the last sign
QCString *ss;
const QCString *ss;
QCString find=qcs;
QCString temp=qcs;
char buf[2];
buf[1]='\0';
int col=0;
int j;
int len;
j = reg.match(temp.data(),0,&len);
......@@ -1372,8 +1413,23 @@ void VhdlDocGen::writeFormatString(const QCString& s,OutputList&ol,const MemberD
{
while (j>=0)
{
bool bString=false;
find=find.left(j);
buf[0]=temp[j];
if(buf[0]=='"' && temp.length()>1)
{
int i=temp.find('"',1);
if(i>0){
find=temp.left(i+1);
j+=i;
bString=true;
}
}
if(optVerilog){
ss=VerilogDocGen::findKeyWord(find);
}
else
ss=VhdlDocGen::findKeyWord(find);
bool k=isNumber(find); // is this a number
if (k)
......@@ -1390,10 +1446,18 @@ void VhdlDocGen::writeFormatString(const QCString& s,OutputList&ol,const MemberD
{
if (j>0)
{
// if(!checkString(find))
VhdlDocGen::writeStringLink(mdef,find,ol);
}
}
startFonts(&buf[0],"vhdlchar",ol);
if(!bString)
startFonts(&buf[0],"vhdlchar",ol);
col+=j+1;
if( col > COL_SIZE)
{
ol.docify(". . . .");
return;
}
QCString st=temp.remove(0,j+1);
find=st;
......@@ -1416,7 +1480,7 @@ void VhdlDocGen::writeFormatString(const QCString& s,OutputList&ol,const MemberD
}//if
else
{
startFonts(find,"vhdlchar",ol);
startFonts(find,"vhdlchar",ol);
}
ol.endBold();
}// writeFormatString
......@@ -1427,10 +1491,24 @@ void VhdlDocGen::writeFormatString(const QCString& s,OutputList&ol,const MemberD
bool VhdlDocGen::isNumber(const QCString& s)
{
static QRegExp regg("[0-9][0-9eEfFbBcCdDaA_.#-+?xXzZ]*");
static QRegExp reggVerilog("[0-9]+[']*[0-9a-fA-FhHoOxXzZ._?]*");
static QRegExp reggVerilog1("['][0-9a-fA-FhHoOxXzZ._?]+");
static bool optVerilog=Config_getBool("OPTIMIZE_OUTPUT_VERILOG");
if (s.isEmpty()) return FALSE;
int j,len;
if(optVerilog){
QCString t=s;
VhdlDocGen::deleteAllChars(t,' ');
j = reggVerilog.match(t.data(),0,&len);
if ((j==0) && (len==(int)t.length())) return true;
j = reggVerilog1.match(t.data(),0,&len);
if ((j==0) && (len==(int)t.length())) return true;
return false;
}
else
j = regg.match(s.data(),0,&len);
if ((j==0) && (len==(int)s.length())) return TRUE;
return FALSE;
......@@ -1444,6 +1522,14 @@ bool VhdlDocGen::isNumber(const QCString& s)
void VhdlDocGen::formatString(const QCString &s, OutputList& ol,const MemberDef* mdef)
{
static bool optVerilog = Config_getBool("OPTIMIZE_OUTPUT_VERILOG");
if(optVerilog){
VhdlDocGen::writeFormatString(s,ol,mdef);
return;
}
QCString qcs = s;
QCString temp;
qcs.stripPrefix(":");
......@@ -1559,7 +1645,10 @@ void VhdlDocGen::writeProcedureProto(OutputList& ol,const ArgumentList* al,const
void VhdlDocGen::writeFunctionProto(OutputList& ol,const ArgumentList* al,const MemberDef* mdef)
{
if (al==0) return;
if (al==0) return;
ArgumentListIterator ali(*al);
Argument *arg;
bool sem=FALSE;
......@@ -1672,7 +1761,9 @@ bool VhdlDocGen::writeFuncProcDocu(
const ArgumentList* al,
bool /*type*/)
{
if (al==0) return FALSE;
static bool optVerilog = Config_getBool("OPTIMIZE_OUTPUT_VERILOG");
if (al==0) return FALSE;
//bool sem=FALSE;
ol.enableAll();
......@@ -1703,11 +1794,15 @@ bool VhdlDocGen::writeFuncProcDocu(
startFonts(arg->defval,"keywordtype",ol);
ol.docify(" ");
}
if(optVerilog)
VerilogDocGen::adjustOpName(arg->name);
ol.endParameterType();
ol.startParameterName(TRUE);
VhdlDocGen::writeFormatString(arg->name,ol,md);
ol.docify(" ");
if (VhdlDocGen::isProcedure(md))
{
startFonts(arg->attrib,"stringliteral",ol);
......@@ -1785,7 +1880,14 @@ QCString VhdlDocGen::convertArgumentListToString(const ArgumentList* al,bool fun
void VhdlDocGen::writeVhdlDeclarations(MemberList* ml,
OutputList& ol,GroupDef* gd,ClassDef* cd,FileDef *fd,NamespaceDef* nd)
{
VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::LIBRARY,FALSE),0,FALSE,VhdlDocGen::LIBRARY);
static bool optVerilog = Config_getBool("OPTIMIZE_OUTPUT_VERILOG");
if(optVerilog){
VerilogDocGen::writeVerilogDeclarations(ml,ol,0,cd);
return;
}
VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::LIBRARY,FALSE),0,FALSE,VhdlDocGen::LIBRARY);
VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::USE,FALSE),0,FALSE,VhdlDocGen::USE);
VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::FUNCTION,FALSE),0,FALSE,VhdlDocGen::FUNCTION);
VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::COMPONENT,FALSE),0,FALSE,VhdlDocGen::COMPONENT);
......@@ -1855,12 +1957,23 @@ bool VhdlDocGen::writeVHDLTypeDocumentation(const MemberDef* mdef, const Definit
ClassDef *cd=(ClassDef*)d;
bool hasParams = FALSE;
bool bParseVerilogFunc=false;
SrcLangExt lang = mdef->getLanguage();
bool optVerilog = lang==SrcLangExt_VHDL || lang==SrcLangExt_VERILOG;
if(optVerilog)
if(!mdef->isVariable())
bParseVerilogFunc=true;
if (cd==0) return hasParams;
QCString ttype=mdef->typeString();
QCString largs=mdef->argsString();
if ((VhdlDocGen::isVhdlFunction(mdef) || VhdlDocGen::isProcedure(mdef) || VhdlDocGen::isProcess(mdef)))
if ((VhdlDocGen::isVhdlFunction(mdef) || VhdlDocGen::isProcedure(mdef) || VhdlDocGen::isProcess(mdef) || bParseVerilogFunc))
{
QCString nn=mdef->typeString();
nn=nn.stripWhiteSpace();
......@@ -1908,6 +2021,38 @@ bool VhdlDocGen::writeVHDLTypeDocumentation(const MemberDef* mdef, const Definit
}
// QCString largs=mdef->argsString();
if(optVerilog)
{
if(mdef->getMemberSpecifiers()==VerilogDocGen::FEATURE)
{
QCString arg=mdef->definition();
int kr=arg.find("\\?");
if(kr>=0)
{
arg=arg.left(kr-2);
arg.stripPrefix("feature");
arg=arg.simplifyWhiteSpace();
arg.stripPrefix(mdef->name().data());
arg.append("{ . . . }");
VhdlDocGen::formatString(arg,ol,mdef);
}
else
{
QCString ttype=mdef->typeString();
ttype.stripPrefix("feature");
VhdlDocGen::formatString(ttype,ol,mdef);
}
return true;
}
if(mdef->getMemberSpecifiers()==VerilogDocGen::PARAMETER)
VhdlDocGen::formatString(largs,ol,mdef);
else
{
QCString ttype=mdef->typeString();
VhdlDocGen::formatString(ttype,ol,mdef);
}
return true;
}
bool c=largs=="context";
bool brec=largs.stripPrefix("record") ;
......@@ -1931,7 +2076,8 @@ bool VhdlDocGen::writeVHDLTypeDocumentation(const MemberDef* mdef, const Definit
ol.docify(" ");
}
}
return hasParams;
return hasParams;
}
void VhdlDocGen::writeTagFile(MemberDef *mdef,FTextStream &tagFile)
......@@ -2334,7 +2480,7 @@ void VhdlDocGen::writePlainVHDLDeclarations(
pack.clear();
}//plainDeclaration
static bool membersHaveSpecificType(MemberList *ml,uint64 type)
bool VhdlDocGen::membersHaveSpecificType(MemberList *ml,uint64 type)
{
if (ml==0) return FALSE;
MemberDef *mdd=0;
......@@ -2422,8 +2568,19 @@ void VhdlDocGen::writeVHDLDeclarations(MemberList* ml,OutputList &ol,
bool VhdlDocGen::writeClassType( ClassDef *& cd,
OutputList &ol ,QCString & cname)
{
int id=cd->protection();
QCString qcs = VhdlDocGen::trTypeString(id+2);
static bool optVerilog = Config_getBool("OPTIMIZE_OUTPUT_VERILOG");
QCString qcs;
if(optVerilog){
if(cd->protection()==Public)
qcs+=" Module";
else
qcs+=" Primitive";
}
else{
int id=cd->protection();
qcs = VhdlDocGen::trTypeString(id+2);
}
cname=VhdlDocGen::getClassName(cd);
ol.startBold();
ol.writeString(qcs.data());
......@@ -2435,6 +2592,12 @@ bool VhdlDocGen::writeClassType( ClassDef *& cd,
QCString VhdlDocGen::trVhdlType(uint64 type,bool sing)
{
static bool optVerilog = Config_getBool("OPTIMIZE_OUTPUT_VERILOG");
if(optVerilog) return VerilogDocGen::convertTypeToString(type,sing);
switch(type)
{
case VhdlDocGen::LIBRARY:
......@@ -2536,7 +2699,13 @@ QCString VhdlDocGen::trDesignUnitMembers()
QCString VhdlDocGen::trDesignUnitListDescription()
{
static bool optVerilog = Config_getBool("OPTIMIZE_OUTPUT_VERILOG");
if(optVerilog)
return "Here is a list of all design unit members with links to "
"the Modules they belong to:";
return "Here is a list of all design unit members with links to "
"the Entities they belong to:";
}
......@@ -2552,6 +2721,9 @@ QCString VhdlDocGen::trDesignUnits()
QCString VhdlDocGen::trFunctionAndProc()
{
if(Config_getBool("OPTIMIZE_OUTPUT_VERILOG"))
return "Functions/Tasks/Always Construct";
return "Functions/Procedures/Processes";
}
......@@ -2560,13 +2732,25 @@ QCString VhdlDocGen::trFunctionAndProc()
void VhdlDocGen::writeStringLink(const MemberDef *mdef,QCString mem, OutputList& ol)
{
if (mdef)
bool optVerilog = Config_getBool("OPTIMIZE_OUTPUT_VERILOG");
MemberDef* memdef=0;
if (mdef)
{
ClassDef *cd=mdef->getClassDef();
if (cd)
{
QCString n=cd->name();
MemberDef* memdef=VhdlDocGen::findMember(n,mem);
if(optVerilog){
if(mem.contains("`"))
memdef = findGlobalMember(mem);
if(memdef==0)
memdef=VerilogDocGen::findMember(n,mem,-1);
}
else
memdef=VhdlDocGen::findMember(n,mem);
if (memdef && memdef->isLinkable())
{
ol.startBold();
......@@ -2772,8 +2956,7 @@ static void initUCF(Entry* root,const char* type,QCString & qcs,int line,QCStr
root->addSubEntry(current);
}
static void writeUCFLink(const MemberDef* mdef,OutputList &ol)
void VhdlDocGen::writeUCFLink(const MemberDef* mdef,OutputList &ol)
{
QCString largs(mdef->argsString());
......
......@@ -245,8 +245,14 @@ class VhdlDocGen
cu->spec==VhdlDocGen::ARCHITECTURE ||
cu->spec==VhdlDocGen::PACKAGE_BODY;
}
static void resetCodeVhdlParserState();
static bool membersHaveSpecificType(MemberList *ml,uint64 type);
static void resetCodeVhdlParserState();
public:
static void writeUCFLink(const MemberDef* mdef,OutputList &ol);
public:
static void startFonts(const QCString& q, const char *keyword,OutputList& ol);
private:
static void findAllArchitectures(QList<QCString>& ql,const ClassDef *cd);
......
......@@ -202,7 +202,6 @@ void VHDLLanguageScanner::parseInput(const char *fileName,const char *fileBuf,En
if (!inLine)
VhdlParser::mapLibPackage(root);
delete[] lineParse;
yyFileName.resize(0);
libUse.clear();
......

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual C++ Express 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Doxygen", "Doxygen.vcproj", "{309C9A4A-94D2-4837-9A11-45B0A6CF35C3}"
ProjectSection(ProjectDependencies) = postProject
{B6BB4771-8A4E-4656-AC08-1EF8AC182F64} = {B6BB4771-8A4E-4656-AC08-1EF8AC182F64}
EndProjectSection
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Express 2012 for Windows Desktop
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Doxygen", "Doxygen.vcxproj", "{309C9A4A-94D2-4837-9A11-45B0A6CF35C3}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qtools", "qtools.vcproj", "{B6BB4771-8A4E-4656-AC08-1EF8AC182F64}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qtools", "qtools.vcxproj", "{B6BB4771-8A4E-4656-AC08-1EF8AC182F64}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doxywizard", "Doxywizard.vcproj", "{77C9C2D3-EA3F-3D59-8B4C-0ED852890172}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doxysearch", "doxysearch.vcproj", "{F3F3408F-F6F7-46C7-BF1E-1FA056E0AE20}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doxyindexer", "doxyindexer.vcproj", "{E543983A-D5BF-4865-B4A1-6D7EF2E1051C}"
ProjectSection(ProjectDependencies) = postProject
{B6BB4771-8A4E-4656-AC08-1EF8AC182F64} = {B6BB4771-8A4E-4656-AC08-1EF8AC182F64}
EndProjectSection
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doxyindexer", "doxyindexer.vcxproj", "{E543983A-D5BF-4865-B4A1-6D7EF2E1051C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
......@@ -59,7 +53,6 @@ Global
{E543983A-D5BF-4865-B4A1-6D7EF2E1051C}.Debug|Win32.ActiveCfg = Debug|Win32
{E543983A-D5BF-4865-B4A1-6D7EF2E1051C}.Debug|Win32.Build.0 = Debug|Win32
{E543983A-D5BF-4865-B4A1-6D7EF2E1051C}.Debug|x64.ActiveCfg = Debug|x64
{E543983A-D5BF-4865-B4A1-6D7EF2E1051C}.Debug|x64.Build.0 = Debug|x64
{E543983A-D5BF-4865-B4A1-6D7EF2E1051C}.Release|Win32.ActiveCfg = Release|Win32
{E543983A-D5BF-4865-B4A1-6D7EF2E1051C}.Release|Win32.Build.0 = Release|Win32
{E543983A-D5BF-4865-B4A1-6D7EF2E1051C}.Release|x64.ActiveCfg = Release|x64
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment