Fix filename backslash escapes in C code (#5947).
This commit is contained in:
parent
d3016b62f5
commit
5ca62de167
1
Changes
1
Changes
|
|
@ -14,6 +14,7 @@ Verilator 5.037 devel
|
||||||
**Other:**
|
**Other:**
|
||||||
|
|
||||||
* Add BADVLTPRAGMA on unknown Verilator pragmas (#5945). [Shou-Li Hsu]
|
* Add BADVLTPRAGMA on unknown Verilator pragmas (#5945). [Shou-Li Hsu]
|
||||||
|
* Fix filename backslash escapes in C code (#5947).
|
||||||
* Fix sign extension of signed compared with unsigned case items (#5968).
|
* Fix sign extension of signed compared with unsigned case items (#5968).
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -355,8 +355,8 @@ public:
|
||||||
// Xml output
|
// Xml output
|
||||||
m_os << "<module_files>\n";
|
m_os << "<module_files>\n";
|
||||||
for (const FileLine* ifp : m_nodeModules) {
|
for (const FileLine* ifp : m_nodeModules) {
|
||||||
m_os << "<file id=\"" << ifp->filenameLetters() << "\" filename=\"" << ifp->filename()
|
m_os << "<file id=\"" << ifp->filenameLetters() << "\" filename=\""
|
||||||
<< "\" language=\"" << ifp->language().ascii() << "\"/>\n";
|
<< ifp->filenameEsc() << "\" language=\"" << ifp->language().ascii() << "\"/>\n";
|
||||||
}
|
}
|
||||||
m_os << "</module_files>\n";
|
m_os << "</module_files>\n";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -268,6 +268,8 @@ public:
|
||||||
string asciiLineCol() const;
|
string asciiLineCol() const;
|
||||||
int filenameno() const VL_MT_SAFE { return m_filenameno; }
|
int filenameno() const VL_MT_SAFE { return m_filenameno; }
|
||||||
string filename() const VL_MT_SAFE { return singleton().numberToName(filenameno()); }
|
string filename() const VL_MT_SAFE { return singleton().numberToName(filenameno()); }
|
||||||
|
// Filename with C string escapes
|
||||||
|
string filenameEsc() const VL_MT_SAFE { return VString::quoteBackslash(filename()); }
|
||||||
bool filenameIsGlobal() const VL_MT_SAFE {
|
bool filenameIsGlobal() const VL_MT_SAFE {
|
||||||
return (filename() == commandLineFilename() || filename() == builtInFilename());
|
return (filename() == commandLineFilename() || filename() == builtInFilename());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -237,7 +237,7 @@ bom [\357\273\277]
|
||||||
return VP_TEXT; }
|
return VP_TEXT; }
|
||||||
<INITIAL,STRIFY>"`__FILE__" { FL_FWDC;
|
<INITIAL,STRIFY>"`__FILE__" { FL_FWDC;
|
||||||
static string rtnfile;
|
static string rtnfile;
|
||||||
rtnfile = '"'; rtnfile += LEXP->curFilelinep()->filename();
|
rtnfile = '"'; rtnfile += LEXP->curFilelinep()->filenameEsc();
|
||||||
rtnfile += '"'; yytext = (char*)rtnfile.c_str(); yyleng = rtnfile.length();
|
rtnfile += '"'; yytext = (char*)rtnfile.c_str(); yyleng = rtnfile.length();
|
||||||
return VP_STRING; }
|
return VP_STRING; }
|
||||||
<INITIAL,STRIFY>"`__LINE__" { FL_FWDC;
|
<INITIAL,STRIFY>"`__LINE__" { FL_FWDC;
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ string VString::upcase(const string& str) VL_PURE {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
string VString::quoteAny(const string& str, char tgt, char esc) {
|
string VString::quoteAny(const string& str, char tgt, char esc) VL_PURE {
|
||||||
string result;
|
string result;
|
||||||
for (const char c : str) {
|
for (const char c : str) {
|
||||||
if (c == tgt) result += esc;
|
if (c == tgt) result += esc;
|
||||||
|
|
|
||||||
|
|
@ -94,11 +94,11 @@ public:
|
||||||
// Convert string to upper case (toupper)
|
// Convert string to upper case (toupper)
|
||||||
static string upcase(const string& str) VL_PURE;
|
static string upcase(const string& str) VL_PURE;
|
||||||
// Insert esc just before tgt
|
// Insert esc just before tgt
|
||||||
static string quoteAny(const string& str, char tgt, char esc);
|
static string quoteAny(const string& str, char tgt, char esc) VL_PURE;
|
||||||
// Replace any \'s with \\ (two consecutive backslashes)
|
// Replace any \'s with \\ (two consecutive backslashes)
|
||||||
static string quoteBackslash(const string& str) { return quoteAny(str, '\\', '\\'); }
|
static string quoteBackslash(const string& str) VL_PURE { return quoteAny(str, '\\', '\\'); }
|
||||||
// Replace any %'s with %%
|
// Replace any %'s with %%
|
||||||
static string quotePercent(const string& str) { return quoteAny(str, '%', '%'); }
|
static string quotePercent(const string& str) VL_PURE { return quoteAny(str, '%', '%'); }
|
||||||
// Replace any %%'s with %
|
// Replace any %%'s with %
|
||||||
static string dequotePercent(const string& str);
|
static string dequotePercent(const string& str);
|
||||||
// Surround a raw string by double quote and escape if necessary
|
// Surround a raw string by double quote and escape if necessary
|
||||||
|
|
|
||||||
|
|
@ -685,8 +685,8 @@ class TaskVisitor final : public VNVisitor {
|
||||||
UASSERT_OBJ(snp, refp, "Missing scoping context");
|
UASSERT_OBJ(snp, refp, "Missing scoping context");
|
||||||
ccallp->addArgsp(snp);
|
ccallp->addArgsp(snp);
|
||||||
// __Vfilenamep
|
// __Vfilenamep
|
||||||
ccallp->addArgsp(new AstCExpr{refp->fileline(),
|
ccallp->addArgsp(new AstCExpr{
|
||||||
"\"" + refp->fileline()->filename() + "\"", 64, true});
|
refp->fileline(), "\"" + refp->fileline()->filenameEsc() + "\"", 64, true});
|
||||||
// __Vlineno
|
// __Vlineno
|
||||||
ccallp->addArgsp(new AstConst(refp->fileline(), refp->fileline()->lineno()));
|
ccallp->addArgsp(new AstConst(refp->fileline(), refp->fileline()->lineno()));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -654,7 +654,7 @@ class TimingControlVisitor final : public VNVisitor {
|
||||||
void addDebugInfo(AstCMethodHard* const methodp) const {
|
void addDebugInfo(AstCMethodHard* const methodp) const {
|
||||||
if (v3Global.opt.protectIds()) return;
|
if (v3Global.opt.protectIds()) return;
|
||||||
FileLine* const flp = methodp->fileline();
|
FileLine* const flp = methodp->fileline();
|
||||||
AstCExpr* const ap = new AstCExpr{flp, '"' + flp->filename() + '"', 0};
|
AstCExpr* const ap = new AstCExpr{flp, '"' + flp->filenameEsc() + '"', 0};
|
||||||
ap->dtypeSetString();
|
ap->dtypeSetString();
|
||||||
methodp->addPinsp(ap);
|
methodp->addPinsp(ap);
|
||||||
AstCExpr* const bp = new AstCExpr{flp, cvtToStr(flp->lineno()), 0};
|
AstCExpr* const bp = new AstCExpr{flp, cvtToStr(flp->lineno()), 0};
|
||||||
|
|
|
||||||
|
|
@ -70,8 +70,8 @@ void V3Waiver::addEntry(V3ErrorCode errorCode, const std::string& filename, cons
|
||||||
}
|
}
|
||||||
|
|
||||||
std::stringstream entry;
|
std::stringstream entry;
|
||||||
entry << "lint_off -rule " << errorCode.ascii() << " -file \"*" << filename << "\" -match \""
|
entry << "lint_off -rule " << errorCode.ascii() << " -file \"*"
|
||||||
<< trimmsg << "\"";
|
<< VString::quoteBackslash(filename) << "\" -match \"" << trimmsg << "\"";
|
||||||
s_waiverList.push_back(entry.str());
|
s_waiverList.push_back(entry.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,20 @@
|
||||||
-Info: some file:100:1: aaaaaaaa
|
-Info: some file:100:1: aaaaaaaa file='some file'
|
||||||
: ... note: In instance 't'
|
: ... note: In instance 't'
|
||||||
100 | $info("aaaaaaaa");
|
100 | $info("aaaaaaaa file='%s'", "some file");
|
||||||
| ^~~~~
|
| ^~~~~
|
||||||
-Info: some file:101:1: bbbbbbbb
|
-Info: some file:101:1: bbbbbbbb file='some file'
|
||||||
: ... note: In instance 't'
|
: ... note: In instance 't'
|
||||||
101 | $info("bbbbbbbb");
|
101 | $info("bbbbbbbb file='%s'", "some file");
|
||||||
| ^~~~~
|
| ^~~~~
|
||||||
-Info: somefile.v:200:1: cccccccc
|
-Info: somefile.v:200:1: cccccccc file='somefile.v'
|
||||||
: ... note: In instance 't'
|
: ... note: In instance 't'
|
||||||
200 | $info("cccccccc");
|
200 | $info("cccccccc file='%s'", "somefile.v");
|
||||||
| ^~~~~
|
| ^~~~~
|
||||||
-Info: /a/somefile.v:300:1: dddddddd
|
-Info: /a/somefile.v:300:1: dddddddd file='/a/somefile.v'
|
||||||
: ... note: In instance 't'
|
: ... note: In instance 't'
|
||||||
300 | $info("dddddddd");
|
300 | $info("dddddddd file='%s'", "/a/somefile.v");
|
||||||
|
| ^~~~~
|
||||||
|
-Info: C:\a\somefile.v:400:1: eeeeeeee file='C:\a\somefile.v'
|
||||||
|
: ... note: In instance 't'
|
||||||
|
400 | $info("eeeeeeee file='%s'", "C:\\a\\somefile.v");
|
||||||
| ^~~~~
|
| ^~~~~
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,12 @@
|
||||||
|
|
||||||
module t;
|
module t;
|
||||||
`line 100 "some file" 0
|
`line 100 "some file" 0
|
||||||
$info("aaaaaaaa");
|
$info("aaaaaaaa file='%s'", `__FILE__);
|
||||||
$info("bbbbbbbb");
|
$info("bbbbbbbb file='%s'", `__FILE__);
|
||||||
`line 200 "somefile.v" 0
|
`line 200 "somefile.v" 0
|
||||||
$info("cccccccc");
|
$info("cccccccc file='%s'", `__FILE__);
|
||||||
`line 300 "/a/somefile.v" 0
|
`line 300 "/a/somefile.v" 0
|
||||||
$info("dddddddd");
|
$info("dddddddd file='%s'", `__FILE__);
|
||||||
|
`line 400 "C:\\a\\somefile.v" 0
|
||||||
|
$info("eeeeeeee file='%s'", `__FILE__);
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
Intentional stop
|
||||||
|
Filename 'C:\some\windows\path\t_stop_winos_bad.v' Length = 39
|
||||||
|
%Error: C:\some\windows\path\t_stop_winos_bad.v:14: Verilog $stop
|
||||||
|
Aborting...
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2024 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.
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.compile(verilator_flags2=['-no-MMD'])
|
||||||
|
|
||||||
|
test.execute(fails=True, expect_filename=test.golden_filename)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||||
|
// any use, without warranty, 2019 by Wilson Snyder.
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
`line 7 "C:\\some\\windows\\path\\t_stop_winos_bad.v" 0
|
||||||
|
|
||||||
|
module t;
|
||||||
|
localparam string FILENAME = `__FILE__;
|
||||||
|
initial begin
|
||||||
|
$write("Intentional stop\n");
|
||||||
|
// Print length to make sure \\ counts as 1 character
|
||||||
|
$write("Filename '%s' Length = %0d\n", FILENAME, FILENAME.len());
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
Loading…
Reference in New Issue