Avoid creating obj_dir with --lint-only
git-svn-id: file://localhost/svn/verilator/trunk/verilator@985 77ca24e4-aefa-0310-84f0-b9a241c72d87
This commit is contained in:
parent
ad591767c9
commit
e4297486ef
6
Changes
6
Changes
|
@ -3,6 +3,12 @@ Revision history for Verilator
|
|||
The contributors that suggested a given feature are shown in []. [by ...]
|
||||
indicates the contributor was also the author of the fix; Thanks!
|
||||
|
||||
* Verilator 3.656 2008/***
|
||||
|
||||
**** Fix Perl warning with --lint-only. [by Ding Xiaoliang]
|
||||
|
||||
**** Avoid creating obj_dir with --lint-only. [Ding Xiaoliang]
|
||||
|
||||
* Verilator 3.656 2008/01/18
|
||||
|
||||
**** Wide VL_CONST_W_#X functions are now made automatically. [Bernard Deadman]
|
||||
|
|
|
@ -91,6 +91,7 @@ if (! GetOptions (
|
|||
"sp!" => sub {$Opt_Sp = 'sp';},
|
||||
"sc!" => sub {$Opt_Sp = 'sc';},
|
||||
"cc!" => sub {$Opt_Sp = 0;},
|
||||
"lint-only!" => sub {$Opt_Sp = 0;},
|
||||
#"ignc!" => ..., # Undocumented debugging, disable $c but don't complain
|
||||
# Additional parameters
|
||||
"<>" => sub {}, # Ignored
|
||||
|
@ -434,7 +435,7 @@ to gcc -MP option.
|
|||
=item --Mdir I<directory>
|
||||
|
||||
Specifies the name of the Make object directory. All generated files will
|
||||
be placed in this directory.
|
||||
be placed in this directory. If not specified, "obj_dir" is used.
|
||||
|
||||
=item --mod-prefix I<topname>
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "verilatedos.h"
|
||||
#include <stdarg.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <iomanip>
|
||||
#include <memory>
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
return new_ofstream_nodepend (filename, append);
|
||||
}
|
||||
static ofstream* new_ofstream_nodepend(const string& filename, bool append=false) {
|
||||
createMakeDir();
|
||||
if (filename != "/dev/null") createMakeDir();
|
||||
if (append) {
|
||||
return new ofstream(filename.c_str(), ios::app);
|
||||
} else {
|
||||
|
@ -54,7 +54,7 @@ public:
|
|||
}
|
||||
}
|
||||
static FILE* new_fopen_w(const string& filename) {
|
||||
createMakeDir();
|
||||
if (filename != "/dev/null") createMakeDir();
|
||||
addTgtDepend(filename);
|
||||
return fopen(filename.c_str(),"w");
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "V3PreShell.h"
|
||||
#include "V3PreProc.h"
|
||||
#include "V3File.h"
|
||||
#include "V3Read.h"
|
||||
|
||||
//######################################################################
|
||||
|
||||
|
@ -64,38 +65,15 @@ protected:
|
|||
}
|
||||
}
|
||||
|
||||
void preproc (FileLine* fl, const string& modname, const string& vppFilename) {
|
||||
void preproc (FileLine* fl, const string& modname, V3Read* readerp) {
|
||||
// Preprocess the given module, putting output in vppFilename
|
||||
unlink(vppFilename.c_str());
|
||||
UINFONL(1," Preprocessing "<<modname<<endl);
|
||||
|
||||
// Open
|
||||
ofstream* ofp = NULL;
|
||||
ostream* osp;
|
||||
if (v3Global.opt.preprocOnly()) {
|
||||
osp = &cout;
|
||||
} else if (!v3Global.opt.keepTempFiles()) { // Must match unlink rule in V3Read.cpp
|
||||
osp = ofp = V3File::new_ofstream_nodepend(vppFilename);
|
||||
} else {
|
||||
osp = ofp = V3File::new_ofstream(vppFilename);
|
||||
}
|
||||
if (osp->fail()) {
|
||||
fl->v3error("Cannot write preprocessor output: "+vppFilename);
|
||||
return;
|
||||
}
|
||||
|
||||
// Preprocess
|
||||
preprocOpen(fl, modname, "Cannot find file containing module: ");
|
||||
while (!s_preprocp->isEof()) {
|
||||
string line = s_preprocp->getline();
|
||||
*osp << line;
|
||||
}
|
||||
|
||||
// Close
|
||||
if (ofp) {
|
||||
ofp->close();
|
||||
delete ofp;
|
||||
osp = ofp = NULL;
|
||||
readerp->ppPushText(line);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,8 +107,8 @@ V3PreProc* V3PreShellImp::s_preprocp = NULL;
|
|||
void V3PreShell::boot(char** env) {
|
||||
V3PreShellImp::s_preImp.boot(env);
|
||||
}
|
||||
void V3PreShell::preproc(FileLine* fl, const string& modname, const string& vppFilename) {
|
||||
V3PreShellImp::s_preImp.preproc(fl, modname, vppFilename);
|
||||
void V3PreShell::preproc(FileLine* fl, const string& modname, V3Read* readerp) {
|
||||
V3PreShellImp::s_preImp.preproc(fl, modname, readerp);
|
||||
}
|
||||
void V3PreShell::preprocInclude(FileLine* fl, const string& modname) {
|
||||
V3PreShellImp::s_preImp.preprocInclude(fl, modname);
|
||||
|
|
|
@ -26,13 +26,15 @@
|
|||
#include "verilatedos.h"
|
||||
#include "V3Error.h"
|
||||
|
||||
class V3Read;
|
||||
|
||||
//============================================================================
|
||||
|
||||
class V3PreShell {
|
||||
// Static class for calling preprocessor
|
||||
public:
|
||||
static void boot(char** env);
|
||||
static void preproc(FileLine* fileline, const string& module, const string& vppFilename);
|
||||
static void preproc(FileLine* fileline, const string& module, V3Read* readerp);
|
||||
static void preprocInclude(FileLine* fileline, const string& module);
|
||||
static string dependFiles() { return ""; } // Perl only
|
||||
static void define(const string& name, const string& value);
|
||||
|
|
|
@ -57,7 +57,7 @@ extern int yydebug;
|
|||
class V3Lexer : public V3LexerBase {
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
V3Lexer(std::istream* arg_yyin) : V3LexerBase(arg_yyin) {}
|
||||
V3Lexer() : V3LexerBase(NULL) {}
|
||||
~V3Lexer() {}
|
||||
// METHODS
|
||||
void stateExitPsl() {
|
||||
|
@ -91,6 +91,29 @@ V3Read::~V3Read() {
|
|||
parserClear();
|
||||
}
|
||||
|
||||
int V3Read::ppInputToLex(char* buf, int max_size) {
|
||||
int got = 0;
|
||||
while (got < max_size // Haven't got enough
|
||||
&& !m_ppBuffers.empty()) { // And something buffered
|
||||
string front = m_ppBuffers.front(); m_ppBuffers.pop_front();
|
||||
int len = front.length();
|
||||
if (len > (max_size-got)) { // Front string too big
|
||||
string remainder = front.substr(max_size-got);
|
||||
front = front.substr(0, max_size-got);
|
||||
m_ppBuffers.push_front(remainder); // Put back remainder for next time
|
||||
len = (max_size-got);
|
||||
}
|
||||
strncpy(buf+got, front.c_str(), len);
|
||||
got += len;
|
||||
}
|
||||
if (debug()>=9) {
|
||||
string out = string(buf,got);
|
||||
cout<<" inputToLex got="<<got<<" '"<<out<<"'"<<endl;
|
||||
}
|
||||
// Note returns 0 at EOF
|
||||
return got;
|
||||
}
|
||||
|
||||
void V3Read::readFile(FileLine* fileline, const string& modfilename, bool inLibrary) {
|
||||
string modname = V3Options::filenameNonExt(modfilename);
|
||||
|
||||
|
@ -98,42 +121,52 @@ void V3Read::readFile(FileLine* fileline, const string& modfilename, bool inLibr
|
|||
m_fileline = new FileLine(fileline);
|
||||
m_inLibrary = inLibrary;
|
||||
|
||||
// Read it
|
||||
string vppfilename = v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"_"+modname+".vpp";
|
||||
V3PreShell::preproc(fileline, modfilename, vppfilename);
|
||||
// Preprocess into m_ppBuffer
|
||||
V3PreShell::preproc(fileline, modfilename, this);
|
||||
|
||||
if (!v3Global.opt.preprocOnly()) {
|
||||
lexFile (vppfilename, modfilename);
|
||||
if (v3Global.opt.preprocOnly() || v3Global.opt.keepTempFiles()) {
|
||||
// Create output file with all the preprocessor output we buffered up
|
||||
string vppfilename = v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"_"+modname+".vpp";
|
||||
ofstream* ofp = NULL;
|
||||
ostream* osp;
|
||||
if (v3Global.opt.preprocOnly()) {
|
||||
osp = &cout;
|
||||
} else {
|
||||
osp = ofp = V3File::new_ofstream(vppfilename);
|
||||
}
|
||||
if (osp->fail()) {
|
||||
fileline->v3error("Cannot write preprocessor output: "+vppfilename);
|
||||
return;
|
||||
} else {
|
||||
for (deque<string>::iterator it = m_ppBuffers.begin(); it!=m_ppBuffers.end(); ++it) {
|
||||
*osp << *it;
|
||||
}
|
||||
if (ofp) {
|
||||
ofp->close();
|
||||
delete ofp; ofp = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!v3Global.opt.keepTempFiles()) { // Must match new_ofstream_nodepend rule in V3PreShell.cpp
|
||||
unlink (vppfilename.c_str());
|
||||
// Parse it
|
||||
if (!v3Global.opt.preprocOnly()) {
|
||||
lexFile (modfilename);
|
||||
}
|
||||
}
|
||||
|
||||
void V3Read::lexFile(const string& vppfilename, const string& modname) {
|
||||
// Open the preprocess output
|
||||
// Don't track a input dependency, as we created the file ourselves
|
||||
ifstream* fsp = V3File::new_ifstream_nodepend(vppfilename);
|
||||
if (fsp->fail()) {
|
||||
m_fileline->v3fatal("Module "<<modname<<" isn't found, or preprocessor errors in "<<vppfilename);
|
||||
}
|
||||
|
||||
void V3Read::lexFile(const string& modname) {
|
||||
// Prepare for lexing
|
||||
UINFO(3,"Lexing "<<vppfilename<<endl);
|
||||
UINFO(3,"Lexing "<<modname<<endl);
|
||||
V3Read::s_readp = this;
|
||||
V3Read::fileline()->warnResetDefault(); // Reenable warnings on each file
|
||||
if (m_lexerp) delete m_lexerp; // Restart from clean slate.
|
||||
m_lexerp = new V3Lexer(fsp);
|
||||
m_lexerp = new V3Lexer();
|
||||
// if (debug()) { m_lexerp->set_debug(~0); }
|
||||
// if (debug()) yydebug = 1;
|
||||
UINFO(4,"Lexing Done "<<vppfilename<<endl);
|
||||
UINFO(4,"Lexing Done "<<modname<<endl);
|
||||
|
||||
// Lex it
|
||||
if (yyparse()) v3fatal("Cannot continue\n");
|
||||
|
||||
// Cleanup
|
||||
fsp->close(); delete fsp; fsp = NULL;
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
|
|
|
@ -45,6 +45,7 @@ class V3Read {
|
|||
deque<string*> m_stringps; // Created strings for later cleanup
|
||||
deque<V3Number*> m_numberps; // Created numbers for later cleanup
|
||||
deque<FileLine> m_lintState; // Current lint state for save/restore
|
||||
deque<string> m_ppBuffers; // Preprocessor->lex buffer of characters to process
|
||||
//int debug() { return 9; }
|
||||
|
||||
protected:
|
||||
|
@ -52,6 +53,7 @@ protected:
|
|||
friend class V3Lexer;
|
||||
friend class V3LexerBase;
|
||||
friend class FileLine;
|
||||
friend class V3PreShellImp;
|
||||
int yylexThis();
|
||||
static bool optPsl();
|
||||
static void ppline (const char* text);
|
||||
|
@ -64,6 +66,9 @@ protected:
|
|||
static bool popBeginKeywords() { if (s_readp->m_inBeginKwd) { s_readp->m_inBeginKwd--; return true; } else return false; }
|
||||
static int lastVerilogState() { return s_readp->m_lastVerilogState; }
|
||||
|
||||
void ppPushText(const string& text) { m_ppBuffers.push_back(text); }
|
||||
int ppInputToLex(char* buf, int max_size);
|
||||
|
||||
public: // But for internal use only
|
||||
static string* newString(const string& text) {
|
||||
// Allocate a string, remembering it so we can reclaim storage at lex end
|
||||
|
@ -100,6 +105,7 @@ public: // But for internal use only
|
|||
static void statePushVlg(); // Parser -> lexer communication
|
||||
static void statePop(); // Parser -> lexer communication
|
||||
static int stateVerilogRecent(); // Parser -> lexer communication
|
||||
static int flexPpInputToLex(char* buf, int max_size) { return s_readp->ppInputToLex(buf,max_size); }
|
||||
|
||||
public:
|
||||
// CREATORS
|
||||
|
@ -118,7 +124,7 @@ public:
|
|||
void readFile(FileLine* fileline, const string& modname, bool inLibrary);
|
||||
|
||||
private:
|
||||
void lexFile(const string& vppfilename, const string& modname);
|
||||
void lexFile(const string& modname);
|
||||
};
|
||||
|
||||
#endif // Guard
|
||||
|
|
|
@ -464,6 +464,7 @@ void process () {
|
|||
V3EmitC::emitcSyms();
|
||||
V3EmitC::emitcTrace();
|
||||
}
|
||||
// Unfortunately we have some lint checks in emitc.
|
||||
V3EmitC::emitc();
|
||||
|
||||
// Statistics
|
||||
|
|
|
@ -33,6 +33,9 @@ extern void yyerrorf(const char* format, ...);
|
|||
|
||||
#define STATE_VERILOG_RECENT S05 // State name for most recent Verilog Version
|
||||
|
||||
#define YY_INPUT(buf,result,max_size) \
|
||||
result = V3Read::flexPpInputToLex(buf,max_size);
|
||||
|
||||
//======================================================================
|
||||
|
||||
#define NEXTLINE() {V3Read::incLineno();}
|
||||
|
|
|
@ -8,7 +8,7 @@ if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
|||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
v_flags2 => ["--lint-only"],
|
||||
v_flags2 => ["--lint-only --Mdir obj_lint_only"],
|
||||
fails=>1,
|
||||
expect=>
|
||||
'%Error: t/t_var_in_assign_bad.v:\d+: Assigning to input variable: value
|
||||
|
@ -16,5 +16,6 @@ compile (
|
|||
%Error: Exiting due to.*',
|
||||
) if $Last_Self->{v3};
|
||||
|
||||
(!-d "obj_lint_only") or $Last_Self->error("%Error: lint-only shouldn't make output directory");
|
||||
ok(1);
|
||||
1;
|
||||
|
|
Loading…
Reference in New Issue