Fix compile error on MinGW, bug887.

This commit is contained in:
Wilson Snyder 2015-02-26 20:40:45 -05:00
parent 6ac672b4a3
commit 751384cb5c
15 changed files with 281 additions and 200 deletions

View File

@ -9,6 +9,8 @@ indicates the contributor was also the author of the fix; Thanks!
**** Fix SystemC arrayed bit vectors, bug886. [David Poole]
**** Fix compile error on MinGW, bug887. [HyungKi Jeong]
* Verilator 3.870 2015-02-12

View File

@ -215,6 +215,7 @@ RAW_OBJS = \
V3Number.o \
V3Options.o \
V3Order.o \
V3Os.o \
V3Param.o \
V3PreShell.o \
V3Premit.o \

View File

@ -29,6 +29,7 @@
#include <algorithm>
#include "V3Global.h"
#include "V3Os.h"
#include "V3EmitMk.h"
#include "V3EmitCBase.h"
@ -46,7 +47,7 @@ public:
}
void putMakeClassEntry(V3OutMkFile& of, const string& name) {
of.puts("\t"+V3Options::filenameNonDirExt(name)+" \\\n");
of.puts("\t"+V3Os::filenameNonDirExt(name)+" \\\n");
}
void emitClassMake() {
@ -184,8 +185,8 @@ public:
const V3StringSet& cppFiles = v3Global.opt.cppFiles();
for (V3StringSet::const_iterator it = cppFiles.begin(); it != cppFiles.end(); ++it) {
string cppfile = *it;
of.puts("\t"+V3Options::filenameNonExt(cppfile)+" \\\n");
string dir = V3Options::filenameDir(cppfile);
of.puts("\t"+V3Os::filenameNonExt(cppfile)+" \\\n");
string dir = V3Os::filenameDir(cppfile);
if (dirs.find(dir) == dirs.end()) dirs.insert(dir);
}
of.puts("\n");
@ -209,7 +210,7 @@ public:
of.puts("\n");
for (V3StringSet::const_iterator it = cppFiles.begin(); it != cppFiles.end(); ++it) {
string cppfile = *it;
string basename = V3Options::filenameNonExt(cppfile);
string basename = V3Os::filenameNonExt(cppfile);
of.puts(basename+".o: "+cppfile+"\n");
of.puts("\t$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $<\n");
}

View File

@ -40,6 +40,7 @@
#include "V3Global.h"
#include "V3File.h"
#include "V3Os.h"
#include "V3PreShell.h"
#include "V3Ast.h"
@ -259,19 +260,11 @@ bool V3File::checkTimes(const string& filename, const string& cmdline) {
return dependImp.checkTimes(filename, cmdline);
}
void V3File::createDir(const string& dirname) {
#ifndef _WIN32
mkdir(dirname.c_str(), 0777);
#else
mkdir(dirname.c_str());
#endif
}
void V3File::createMakeDir() {
static bool created = false;
if (!created) {
created = true;
createDir(v3Global.opt.makeDir());
V3Os::createDir(v3Global.opt.makeDir());
}
}

View File

@ -67,7 +67,6 @@ public:
static bool checkTimes(const string& filename, const string& cmdline);
// Directory utilities
static void createDir(const string& dirname);
static void createMakeDir();
};

View File

@ -36,6 +36,7 @@
#include "V3Global.h"
#include "V3String.h"
#include "V3Os.h"
#include "V3Options.h"
#include "V3Error.h"
#include "V3File.h"
@ -197,83 +198,6 @@ V3LangCode::V3LangCode (const char* textp) {
//######################################################################
// File searching
string V3Options::filenameFromDirBase (const string& dir, const string& basename) {
// Don't return ./{filename} because if filename was absolute, that makes it relative
if (dir == ".") return basename;
else return dir+"/"+basename;
}
string V3Options::filenameDir (const string& filename) {
string::size_type pos;
if ((pos = filename.rfind("/")) != string::npos) {
return filename.substr(0,pos);
} else {
return ".";
}
}
string V3Options::filenameNonDir (const string& filename) {
string::size_type pos;
if ((pos = filename.rfind("/")) != string::npos) {
return filename.substr(pos+1);
} else {
return filename;
}
}
string V3Options::filenameNonExt (const string& filename) {
string base = filenameNonDir(filename);
string::size_type pos;
if ((pos = base.find(".")) != string::npos) {
base.erase(pos);
}
return base;
}
string V3Options::filenameSubstitute (const string& filename) {
string out;
enum { NONE, PAREN, CURLY } brackets = NONE;
for (string::size_type pos = 0; pos < filename.length(); ++pos) {
if ((filename[pos] == '$') && (pos+1 < filename.length())) {
switch (filename[pos+1]) {
case '{': brackets = CURLY; break;
case '(': brackets = PAREN; break;
default: brackets = NONE; break;
}
if (brackets != NONE) pos = pos+1;
string::size_type endpos = pos+1;
while (((endpos+1) < filename.length()) &&
(((brackets==NONE) && (isalnum(filename[endpos+1]) || filename[endpos+1]=='_')) ||
((brackets==CURLY) && (filename[endpos+1]!='}')) ||
((brackets==PAREN) && (filename[endpos+1]!=')'))))
++endpos;
// Catch bracket errors
if (((brackets==CURLY) && (filename[endpos+1]!='}')) ||
((brackets==PAREN) && (filename[endpos+1]!=')'))) {
v3fatal("Unmatched brackets in variable substitution in file: "+filename);
}
string envvar = filename.substr(pos+1,endpos-pos);
const char* envvalue = NULL;
if (envvar != "") envvalue = getenv(envvar.c_str());
if (envvalue) {
out += envvalue;
if (brackets==NONE) pos = endpos;
else pos = endpos+1;
} else {
out += filename[pos]; // *pos == '$'
}
} else {
out += filename[pos];
}
}
return out;
}
bool V3Options::filenameIsRel(const string& filename) {
return (filename.length()>0 && filename[0] != '/');
}
bool V3Options::fileStatDir(const string& filename) {
struct stat sstat; // Stat information
int err = stat(filename.c_str(), &sstat);
@ -306,8 +230,8 @@ string V3Options::fileExists (const string& filename) {
// is quite slow; presumably because of re-reading each directory
// many times. So we read a whole dir at once and cache it
string dir = filenameDir(filename);
string basename = filenameNonDir(filename);
string dir = V3Os::filenameDir(filename);
string basename = V3Os::filenameNonDir(filename);
V3OptionsImp::DirMap::iterator diriter = m_impp->m_dirMap.find(dir);
if (diriter == m_impp->m_dirMap.end()) {
@ -332,14 +256,14 @@ string V3Options::fileExists (const string& filename) {
return ""; // Not found
}
// Check if it is a directory, ignore if so
string filenameOut = filenameFromDirBase (dir, basename);
string filenameOut = V3Os::filenameFromDirBase (dir, basename);
if (!fileStatNormal(filenameOut)) return ""; // Directory
return filenameOut;
}
string V3Options::filePathCheckOneDir(const string& modname, const string& dirname) {
for (list<string>::iterator extIter=m_impp->m_libExtVs.begin(); extIter!=m_impp->m_libExtVs.end(); ++extIter) {
string fn = filenameFromDirBase(dirname, modname+*extIter);
string fn = V3Os::filenameFromDirBase(dirname, modname+*extIter);
string exists = fileExists(fn);
if (exists!="") {
// Strip ./, it just looks ugly
@ -385,14 +309,14 @@ void V3Options::filePathLookedMsg(FileLine* fl, const string& modname) {
for (list<string>::iterator dirIter=m_impp->m_incDirUsers.begin();
dirIter!=m_impp->m_incDirUsers.end(); ++dirIter) {
for (list<string>::iterator extIter=m_impp->m_libExtVs.begin(); extIter!=m_impp->m_libExtVs.end(); ++extIter) {
string fn = filenameFromDirBase(*dirIter,modname+*extIter);
string fn = V3Os::filenameFromDirBase(*dirIter,modname+*extIter);
fl->v3error(" "<<fn<<endl);
}
}
for (list<string>::iterator dirIter=m_impp->m_incDirFallbacks.begin();
dirIter!=m_impp->m_incDirFallbacks.end(); ++dirIter) {
for (list<string>::iterator extIter=m_impp->m_libExtVs.begin(); extIter!=m_impp->m_libExtVs.end(); ++extIter) {
string fn = filenameFromDirBase(*dirIter,modname+*extIter);
string fn = V3Os::filenameFromDirBase(*dirIter,modname+*extIter);
fl->v3error(" "<<fn<<endl);
}
}
@ -404,7 +328,7 @@ void V3Options::filePathLookedMsg(FileLine* fl, const string& modname) {
//! If we recognize the extension, use its language, otherwise, use the
//! default language.
V3LangCode V3Options::fileLanguage(const string &filename) {
string ext = filenameNonDir(filename);
string ext = V3Os::filenameNonDir(filename);
string::size_type pos;
if ((pos = ext.rfind(".")) != string::npos) {
ext.erase(0, pos + 1);
@ -417,63 +341,27 @@ V3LangCode V3Options::fileLanguage(const string &filename) {
}
void V3Options::unlinkRegexp(const string& dir, const string& regexp) {
if (DIR* dirp = opendir(dir.c_str())) {
while (struct dirent* direntp = readdir(dirp)) {
if (VString::wildmatch(direntp->d_name, regexp.c_str())) {
string fullname = dir + "/" + string(direntp->d_name);
unlink (fullname.c_str());
}
}
closedir(dirp);
}
}
//######################################################################
// Environment
string V3Options::getenvStr(const string& envvar, const string& defaultValue) {
if (const char* envvalue = getenv(envvar.c_str())) {
return envvalue;
} else {
return defaultValue;
}
}
void V3Options::setenvStr(const string& envvar, const string& value, const string& why) {
if (why != "") {
UINFO(1,"export "<<envvar<<"="<<value<<" # "<<why<<endl);
} else {
UINFO(1,"export "<<envvar<<"="<<value<<endl);
}
#if defined(_BSD_SOURCE) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L)
setenv(envvar.c_str(),value.c_str(),true);
#else
//setenv() replaced by putenv() in MinGW/Solaris environment. Prototype is different
//putenv() requires NAME=VALUE format
string vareq = envvar + "=" + value;
putenv(const_cast<char*>(vareq.c_str()));
#endif
}
string V3Options::getenvPERL() {
return getenvStr("PERL","perl");
return V3Os::getenvStr("PERL","perl");
}
string V3Options::getenvSYSTEMC() {
string var = getenvStr("SYSTEMC","");
string var = V3Os::getenvStr("SYSTEMC","");
if (var == "" && string(DEFENV_SYSTEMC) != "") {
var = DEFENV_SYSTEMC;
setenvStr("SYSTEMC", var, "Hardcoded at build time");
V3Os::setenvStr("SYSTEMC", var, "Hardcoded at build time");
}
return var;
}
string V3Options::getenvSYSTEMC_ARCH() {
string var = getenvStr("SYSTEMC_ARCH","");
string var = V3Os::getenvStr("SYSTEMC_ARCH","");
if (var == "" && string(DEFENV_SYSTEMC_ARCH) != "") {
var = DEFENV_SYSTEMC_ARCH;
setenvStr("SYSTEMC_ARCH", var, "Hardcoded at build time");
V3Os::setenvStr("SYSTEMC_ARCH", var, "Hardcoded at build time");
}
if (var == "") {
#if defined (__MINGW32__)
@ -491,16 +379,16 @@ string V3Options::getenvSYSTEMC_ARCH() {
else if (VString::wildmatch(sysname.c_str(), "*cygwin*")) { var ="cygwin"; }
else { var = "linux"; }
#endif
setenvStr("SYSTEMC_ARCH", var,"From sysname '"+sysname+"'");
V3Os::setenvStr("SYSTEMC_ARCH", var,"From sysname '"+sysname+"'");
}
return var;
}
string V3Options::getenvSYSTEMC_INCLUDE() {
string var = getenvStr("SYSTEMC_INCLUDE","");
string var = V3Os::getenvStr("SYSTEMC_INCLUDE","");
if (var == "" && string(DEFENV_SYSTEMC_INCLUDE) != "") {
var = DEFENV_SYSTEMC_INCLUDE;
setenvStr("SYSTEMC_INCLUDE", var, "Hardcoded at build time");
V3Os::setenvStr("SYSTEMC_INCLUDE", var, "Hardcoded at build time");
}
if (var == "") {
string sc = getenvSYSTEMC();
@ -517,10 +405,10 @@ string V3Options::getenvSYSTEMC_INCLUDE() {
}
string V3Options::getenvSYSTEMC_LIBDIR() {
string var = getenvStr("SYSTEMC_LIBDIR","");
string var = V3Os::getenvStr("SYSTEMC_LIBDIR","");
if (var == "" && string(DEFENV_SYSTEMC_LIBDIR) != "") {
var = DEFENV_SYSTEMC_LIBDIR;
setenvStr("SYSTEMC_LIBDIR", var, "Hardcoded at build time");
V3Os::setenvStr("SYSTEMC_LIBDIR", var, "Hardcoded at build time");
}
if (var == "") {
string sc = getenvSYSTEMC();
@ -546,26 +434,26 @@ string V3Options::getenvSYSTEMPERL() {
string V3Options::getenvSYSTEMPERLGuts() {
// Get SYSTEMPERL when SYSTEMPERL_INCLUDE has already been tested
string var = getenvStr("SYSTEMPERL","");
string var = V3Os::getenvStr("SYSTEMPERL","");
if (var == "" && string(DEFENV_SYSTEMPERL) != "") {
var = DEFENV_SYSTEMPERL;
setenvStr("SYSTEMPERL", var, "Hardcoded at build time");
V3Os::setenvStr("SYSTEMPERL", var, "Hardcoded at build time");
}
return var;
}
string V3Options::getenvSYSTEMPERL_INCLUDE() {
string var = getenvStr("SYSTEMPERL_INCLUDE","");
string var = V3Os::getenvStr("SYSTEMPERL_INCLUDE","");
if (var == "") {
string sp_src = V3Options::getenvSYSTEMPERLGuts()+"/src";
if (V3Options::fileStatNormal(sp_src+"/systemperl.h")) {
var = sp_src;
setenvStr ("SYSTEMPERL_INCLUDE", var, "From $SYSTEMPERL/src");
V3Os::setenvStr ("SYSTEMPERL_INCLUDE", var, "From $SYSTEMPERL/src");
} else if (string(DEFENV_SYSTEMPERL_INCLUDE) != "") {
// Note if SYSTEMPERL is DEFENVed, then SYSTEMPERL_INCLUDE is also DEFENVed
// So we don't need to sweat testing DEFENV_SYSTEMPERL also
var = DEFENV_SYSTEMPERL_INCLUDE;
setenvStr("SYSTEMPERL_INCLUDE", var, "Hardcoded at build time");
V3Os::setenvStr("SYSTEMPERL_INCLUDE", var, "Hardcoded at build time");
}
}
// Only correct or check it if we really need the value
@ -584,10 +472,10 @@ string V3Options::getenvSYSTEMPERL_INCLUDE() {
}
string V3Options::getenvVERILATOR_ROOT() {
string var = getenvStr("VERILATOR_ROOT","");
string var = V3Os::getenvStr("VERILATOR_ROOT","");
if (var == "" && string(DEFENV_VERILATOR_ROOT) != "") {
var = DEFENV_VERILATOR_ROOT;
setenvStr("VERILATOR_ROOT", var, "Hardcoded at build time");
V3Os::setenvStr("VERILATOR_ROOT", var, "Hardcoded at build time");
}
if (var == "") {
v3fatal("$VERILATOR_ROOT needs to be in environment\n");
@ -639,7 +527,7 @@ void V3Options::parseOpts (FileLine* fl, int argc, char** argv) {
// Default prefix to the filename
if (prefix()=="" && topModule()!="") m_prefix = string("V")+topModule();
if (prefix()=="" && vFilesList.size()>=1) m_prefix = string("V")+filenameNonExt(*(vFilesList.begin()));
if (prefix()=="" && vFilesList.size()>=1) m_prefix = string("V")+V3Os::filenameNonExt(*(vFilesList.begin()));
if (modPrefix()=="") m_modPrefix = prefix();
// Find files in makedir
@ -1126,7 +1014,7 @@ void V3Options::parseOptsFile(FileLine* fl, const string& filename, bool rel) {
}
// Path
string optdir = (rel ? V3Options::filenameDir(filename) : ".");
string optdir = (rel ? V3Os::filenameDir(filename) : ".");
// Convert to argv style arg list and parse them
char* argv [args.size()+1];
@ -1139,8 +1027,8 @@ void V3Options::parseOptsFile(FileLine* fl, const string& filename, bool rel) {
//======================================================================
string V3Options::parseFileArg(const string& optdir, const string& relfilename) {
string filename = V3Options::filenameSubstitute(relfilename);
if (optdir != "." && filenameIsRel(filename)) {
string filename = V3Os::filenameSubstitute(relfilename);
if (optdir != "." && V3Os::filenameIsRel(filename)) {
filename = optdir + "/" + filename;
}
return filename;
@ -1190,15 +1078,15 @@ void V3Options::showVersion(bool verbose) {
cout <<endl;
cout << "Environment:\n";
cout << " PERL = " << getenvStr("PERL","")<<endl;
cout << " SYSTEMC = " << getenvStr("SYSTEMC","")<<endl;
cout << " SYSTEMC_ARCH = " << getenvStr("SYSTEMC_ARCH","")<<endl;
cout << " SYSTEMC_INCLUDE = " << getenvStr("SYSTEMC_INCLUDE","")<<endl;
cout << " SYSTEMC_LIBDIR = " << getenvStr("SYSTEMC_LIBDIR","")<<endl;
cout << " SYSTEMPERL = " << getenvStr("SYSTEMPERL","")<<endl;
cout << " SYSTEMPERL_INCLUDE = " << getenvStr("SYSTEMPERL_INCLUDE","")<<endl;
cout << " VERILATOR_ROOT = " << getenvStr("VERILATOR_ROOT","")<<endl;
cout << " VERILATOR_BIN = " << getenvStr("VERILATOR_BIN","")<<endl; // wrapper uses this
cout << " PERL = " << V3Os::getenvStr("PERL","")<<endl;
cout << " SYSTEMC = " << V3Os::getenvStr("SYSTEMC","")<<endl;
cout << " SYSTEMC_ARCH = " << V3Os::getenvStr("SYSTEMC_ARCH","")<<endl;
cout << " SYSTEMC_INCLUDE = " << V3Os::getenvStr("SYSTEMC_INCLUDE","")<<endl;
cout << " SYSTEMC_LIBDIR = " << V3Os::getenvStr("SYSTEMC_LIBDIR","")<<endl;
cout << " SYSTEMPERL = " << V3Os::getenvStr("SYSTEMPERL","")<<endl;
cout << " SYSTEMPERL_INCLUDE = " << V3Os::getenvStr("SYSTEMPERL_INCLUDE","")<<endl;
cout << " VERILATOR_ROOT = " << V3Os::getenvStr("VERILATOR_ROOT","")<<endl;
cout << " VERILATOR_BIN = " << V3Os::getenvStr("VERILATOR_BIN","")<<endl; // wrapper uses this
}
//======================================================================
@ -1306,7 +1194,7 @@ void V3Options::setDebugSrcLevel(const string& srcfile, int level) {
int V3Options::debugSrcLevel(const string& srcfile_path, int default_level) {
// For simplicity, calling functions can just use __FILE__ for srcfile.
// That means though we need to cleanup the filename from ../Foo.cpp -> Foo
string srcfile = V3Options::filenameNonDirExt(srcfile_path);
string srcfile = V3Os::filenameNonDirExt(srcfile_path);
DebugSrcMap::iterator iter = m_debugSrcs.find(srcfile);
if (iter!=m_debugSrcs.end()) {
return iter->second;

View File

@ -169,8 +169,6 @@ class V3Options {
bool parseLangExt(const char* swp, const char* langswp, const V3LangCode& lc);
string filePathCheckOneDir(const string& modname, const string& dirname);
static string getenvStr(const string& envvar, const string& defaultValue);
static void setenvStr(const string& envvar, const string& value, const string& why);
static string getenvSYSTEMPERLGuts();
public:
@ -306,16 +304,6 @@ class V3Options {
void parseOptsList (FileLine* fl, const string& optdir, int argc, char** argv);
void parseOptsFile (FileLine* fl, const string& filename, bool rel);
// METHODS (generic file utilities)
static string filenameFromDirBase (const string& dir, const string& basename);
static string filenameNonDir (const string& filename); ///< Return non-directory part of filename
static string filenameNonExt (const string& filename); ///< Return non-extensioned (no .) part of filename
static string filenameNonDirExt (const string& filename) { return filenameNonExt(filenameNonDir(filename)); } ///< Return basename of filename
static string filenameDir (const string& filename); ///< Return directory part of filename
static string filenameSubstitute (const string& filename); ///< Return filename with env vars removed
static bool filenameIsRel (const string& filename); ///< True if relative
static void unlinkRegexp(const string& dir, const string& regexp);
// METHODS (environment)
// Most of these may be built into the executable with --enable-defenv,
// see the README. If adding new variables, also see src/Makefile_obj.in

169
src/V3Os.cpp Normal file
View File

@ -0,0 +1,169 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Os-specific function wrapper
//
// Code available from: http://www.veripool.org/verilator
//
//*************************************************************************
//
// Copyright 2003-2015 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.
//
// Verilator 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.
//
//*************************************************************************
#include "config_build.h"
#include "verilatedos.h"
#include <cstdarg>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <cerrno>
#include <fcntl.h>
#include <iomanip>
#include <memory>
#if defined(WIN32) || defined(__MINGW32__)
# include <direct.h> // mkdir
#endif
#include "V3Global.h"
#include "V3String.h"
#include "V3Os.h"
//######################################################################
// Environment
string V3Os::getenvStr(const string& envvar, const string& defaultValue) {
if (const char* envvalue = getenv(envvar.c_str())) {
return envvalue;
} else {
return defaultValue;
}
}
void V3Os::setenvStr(const string& envvar, const string& value, const string& why) {
if (why != "") {
UINFO(1,"export "<<envvar<<"="<<value<<" # "<<why<<endl);
} else {
UINFO(1,"export "<<envvar<<"="<<value<<endl);
}
#if defined(_BSD_SOURCE) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L)
setenv(envvar.c_str(),value.c_str(),true);
#else
//setenv() replaced by putenv() in MinGW/Solaris environment. Prototype is different
//putenv() requires NAME=VALUE format
string vareq = envvar + "=" + value;
putenv(const_cast<char*>(vareq.c_str()));
#endif
}
//######################################################################
// Generic filename utilities
string V3Os::filenameFromDirBase (const string& dir, const string& basename) {
// Don't return ./{filename} because if filename was absolute, that makes it relative
if (dir == ".") return basename;
else return dir+"/"+basename;
}
string V3Os::filenameDir (const string& filename) {
string::size_type pos;
if ((pos = filename.rfind("/")) != string::npos) {
return filename.substr(0,pos);
} else {
return ".";
}
}
string V3Os::filenameNonDir (const string& filename) {
string::size_type pos;
if ((pos = filename.rfind("/")) != string::npos) {
return filename.substr(pos+1);
} else {
return filename;
}
}
string V3Os::filenameNonExt (const string& filename) {
string base = filenameNonDir(filename);
string::size_type pos;
if ((pos = base.find(".")) != string::npos) {
base.erase(pos);
}
return base;
}
string V3Os::filenameSubstitute (const string& filename) {
string out;
enum { NONE, PAREN, CURLY } brackets = NONE;
for (string::size_type pos = 0; pos < filename.length(); ++pos) {
if ((filename[pos] == '$') && (pos+1 < filename.length())) {
switch (filename[pos+1]) {
case '{': brackets = CURLY; break;
case '(': brackets = PAREN; break;
default: brackets = NONE; break;
}
if (brackets != NONE) pos = pos+1;
string::size_type endpos = pos+1;
while (((endpos+1) < filename.length()) &&
(((brackets==NONE) && (isalnum(filename[endpos+1]) || filename[endpos+1]=='_')) ||
((brackets==CURLY) && (filename[endpos+1]!='}')) ||
((brackets==PAREN) && (filename[endpos+1]!=')'))))
++endpos;
// Catch bracket errors
if (((brackets==CURLY) && (filename[endpos+1]!='}')) ||
((brackets==PAREN) && (filename[endpos+1]!=')'))) {
v3fatal("Unmatched brackets in variable substitution in file: "+filename);
}
string envvar = filename.substr(pos+1,endpos-pos);
const char* envvalue = NULL;
if (envvar != "") envvalue = getenv(envvar.c_str());
if (envvalue) {
out += envvalue;
if (brackets==NONE) pos = endpos;
else pos = endpos+1;
} else {
out += filename[pos]; // *pos == '$'
}
} else {
out += filename[pos];
}
}
return out;
}
bool V3Os::filenameIsRel(const string& filename) {
return (filename.length()>0 && filename[0] != '/');
}
//######################################################################
// Directory utilities
void V3Os::createDir(const string& dirname) {
#if defined(_WIN32) || defined(__MINGW32__)
mkdir(dirname.c_str());
#else
mkdir(dirname.c_str(), 0777);
#endif
}
void V3Os::unlinkRegexp(const string& dir, const string& regexp) {
if (DIR* dirp = opendir(dir.c_str())) {
while (struct dirent* direntp = readdir(dirp)) {
if (VString::wildmatch(direntp->d_name, regexp.c_str())) {
string fullname = dir + "/" + string(direntp->d_name);
unlink (fullname.c_str());
}
}
closedir(dirp);
}
}

51
src/V3Os.h Normal file
View File

@ -0,0 +1,51 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Os-specific function wrapper
//
// Code available from: http://www.veripool.org/verilator
//
//*************************************************************************
//
// Copyright 2003-2015 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.
//
// Verilator 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.
//
//*************************************************************************
#ifndef _V3OS_H_
#define _V3OS_H_ 1
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include <cstdio>
//============================================================================
// V3Os: OS static class
class V3Os {
public:
// METHODS (environment)
static string getenvStr(const string& envvar, const string& defaultValue);
static void setenvStr(const string& envvar, const string& value, const string& why);
// METHODS (generic filename utilities)
static string filenameFromDirBase (const string& dir, const string& basename);
static string filenameNonDir (const string& filename); ///< Return non-directory part of filename
static string filenameNonExt (const string& filename); ///< Return non-extensioned (no .) part of filename
static string filenameNonDirExt (const string& filename) { return filenameNonExt(filenameNonDir(filename)); } ///< Return basename of filename
static string filenameDir (const string& filename); ///< Return directory part of filename
static string filenameSubstitute (const string& filename); ///< Return filename with env vars removed
static bool filenameIsRel (const string& filename); ///< True if relative
// METHODS (directory utilities)
static void createDir(const string& dirname);
static void unlinkRegexp(const string& dir, const string& regexp);
};
#endif // Guard

View File

@ -36,6 +36,7 @@
#include "V3Error.h"
#include "V3Global.h"
#include "V3Os.h"
#include "V3Ast.h"
#include "V3File.h"
#include "V3ParseImp.h"
@ -91,7 +92,7 @@ size_t V3ParseImp::ppInputToLex(char* buf, size_t max_size) {
void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool inLibrary,
const string& errmsg) { // "" for no error, make fake node
string modname = V3Options::filenameNonExt(modfilename);
string modname = V3Os::filenameNonExt(modfilename);
UINFO(2,__FUNCTION__<<": "<<modname<<(inLibrary?" [LIB]":"")<<endl);
m_fileline = new FileLine(fileline);

View File

@ -68,6 +68,7 @@
#include "V3Localize.h"
#include "V3Name.h"
#include "V3Order.h"
#include "V3Os.h"
#include "V3Param.h"
#include "V3Parse.h"
#include "V3ParseSym.h"
@ -660,9 +661,9 @@ int main(int argc, char** argv, char** env) {
//--FRONTEND------------------
// Cleanup
V3Options::unlinkRegexp(v3Global.opt.makeDir(), v3Global.opt.prefix()+"_*.tree");
V3Options::unlinkRegexp(v3Global.opt.makeDir(), v3Global.opt.prefix()+"_*.dot");
V3Options::unlinkRegexp(v3Global.opt.makeDir(), v3Global.opt.prefix()+"_*.txt");
V3Os::unlinkRegexp(v3Global.opt.makeDir(), v3Global.opt.prefix()+"_*.tree");
V3Os::unlinkRegexp(v3Global.opt.makeDir(), v3Global.opt.prefix()+"_*.dot");
V3Os::unlinkRegexp(v3Global.opt.makeDir(), v3Global.opt.prefix()+"_*.txt");
// Read first filename
v3Global.readFiles();

View File

@ -21,6 +21,8 @@
// Cheat for speed and compile .cpp files into one object
#define _V3ERROR_NO_GLOBAL_ 1
#include "V3Error.cpp"
#include "V3String.cpp"
#include "V3Os.cpp"
#include "VlcTop.cpp"
#include "VlcOptions.h"
@ -130,19 +132,6 @@ void VlcOptions::showVersion(bool verbose) {
cout << "See http://www.veripool.org/verilator for documentation\n";
}
//######################################################################
// File searching
// (TODO: Make a V3Os with these functions and share with Verilator)
string VlcOptions::filenameNonDir (const string& filename) {
string::size_type pos;
if ((pos = filename.rfind("/")) != string::npos) {
return filename.substr(pos+1);
} else {
return filename;
}
}
//######################################################################
int main(int argc, char** argv, char** env) {

View File

@ -77,9 +77,6 @@ public:
// METHODS (from main)
static string version();
// METHODS (file searching)
static string filenameNonDir(const string& filename);
};
//######################################################################

View File

@ -18,8 +18,8 @@
//
//*************************************************************************
// Cheat for speed and compile .cpp files into one object
#include "V3Error.h"
#include "V3Os.h"
#include "VlcOptions.h"
#include "VlcTop.h"
@ -194,12 +194,12 @@ void VlcTop::annotateCalcNeeded() {
void VlcTop::annotateOutputFiles(const string& dirname) {
// Create if uncreated, ignore errors
mkdir(dirname.c_str(), 0777);
V3Os::createDir(dirname);
for (VlcSources::NameMap::iterator sit=m_sources.begin(); sit!=m_sources.end(); ++sit) {
VlcSource& source = sit->second;
if (!source.needed()) continue;
string filename = source.name();
string outfilename = dirname+"/"+VlcOptions::filenameNonDir(filename);
string outfilename = dirname+"/"+V3Os::filenameNonDir(filename);
UINFO(1,"annotateOutputFile "<<filename<<" -> "<<outfilename<<endl);

View File

@ -42,6 +42,7 @@ private:
VlcSources m_sources; //< List of all source files to annotate
// METHODS
void createDir(const string& dirname);
void annotateCalc();
void annotateCalcNeeded();
void annotateOutputFiles(const string& dirname);