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:
Wilson Snyder 2008-01-31 14:49:27 +00:00
parent ad591767c9
commit e4297486ef
11 changed files with 87 additions and 55 deletions

View File

@ -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]

View File

@ -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>

View File

@ -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>

View File

@ -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");
}

View File

@ -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);

View File

@ -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);

View File

@ -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;
}
//======================================================================

View File

@ -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

View File

@ -464,6 +464,7 @@ void process () {
V3EmitC::emitcSyms();
V3EmitC::emitcTrace();
}
// Unfortunately we have some lint checks in emitc.
V3EmitC::emitc();
// Statistics

View File

@ -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();}

View File

@ -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;