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:**
|
||||
|
||||
* 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).
|
||||
|
||||
|
||||
|
|
|
@ -355,8 +355,8 @@ public:
|
|||
// Xml output
|
||||
m_os << "<module_files>\n";
|
||||
for (const FileLine* ifp : m_nodeModules) {
|
||||
m_os << "<file id=\"" << ifp->filenameLetters() << "\" filename=\"" << ifp->filename()
|
||||
<< "\" language=\"" << ifp->language().ascii() << "\"/>\n";
|
||||
m_os << "<file id=\"" << ifp->filenameLetters() << "\" filename=\""
|
||||
<< ifp->filenameEsc() << "\" language=\"" << ifp->language().ascii() << "\"/>\n";
|
||||
}
|
||||
m_os << "</module_files>\n";
|
||||
}
|
||||
|
|
|
@ -268,6 +268,8 @@ public:
|
|||
string asciiLineCol() const;
|
||||
int filenameno() const VL_MT_SAFE { return m_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 {
|
||||
return (filename() == commandLineFilename() || filename() == builtInFilename());
|
||||
}
|
||||
|
|
|
@ -237,7 +237,7 @@ bom [\357\273\277]
|
|||
return VP_TEXT; }
|
||||
<INITIAL,STRIFY>"`__FILE__" { FL_FWDC;
|
||||
static string rtnfile;
|
||||
rtnfile = '"'; rtnfile += LEXP->curFilelinep()->filename();
|
||||
rtnfile = '"'; rtnfile += LEXP->curFilelinep()->filenameEsc();
|
||||
rtnfile += '"'; yytext = (char*)rtnfile.c_str(); yyleng = rtnfile.length();
|
||||
return VP_STRING; }
|
||||
<INITIAL,STRIFY>"`__LINE__" { FL_FWDC;
|
||||
|
|
|
@ -91,7 +91,7 @@ string VString::upcase(const string& str) VL_PURE {
|
|||
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;
|
||||
for (const char c : str) {
|
||||
if (c == tgt) result += esc;
|
||||
|
|
|
@ -94,11 +94,11 @@ public:
|
|||
// Convert string to upper case (toupper)
|
||||
static string upcase(const string& str) VL_PURE;
|
||||
// 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)
|
||||
static string quoteBackslash(const string& str) { return quoteAny(str, '\\', '\\'); }
|
||||
static string quoteBackslash(const string& str) VL_PURE { return quoteAny(str, '\\', '\\'); }
|
||||
// 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 %
|
||||
static string dequotePercent(const string& str);
|
||||
// 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");
|
||||
ccallp->addArgsp(snp);
|
||||
// __Vfilenamep
|
||||
ccallp->addArgsp(new AstCExpr{refp->fileline(),
|
||||
"\"" + refp->fileline()->filename() + "\"", 64, true});
|
||||
ccallp->addArgsp(new AstCExpr{
|
||||
refp->fileline(), "\"" + refp->fileline()->filenameEsc() + "\"", 64, true});
|
||||
// __Vlineno
|
||||
ccallp->addArgsp(new AstConst(refp->fileline(), refp->fileline()->lineno()));
|
||||
}
|
||||
|
|
|
@ -654,7 +654,7 @@ class TimingControlVisitor final : public VNVisitor {
|
|||
void addDebugInfo(AstCMethodHard* const methodp) const {
|
||||
if (v3Global.opt.protectIds()) return;
|
||||
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();
|
||||
methodp->addPinsp(ap);
|
||||
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;
|
||||
entry << "lint_off -rule " << errorCode.ascii() << " -file \"*" << filename << "\" -match \""
|
||||
<< trimmsg << "\"";
|
||||
entry << "lint_off -rule " << errorCode.ascii() << " -file \"*"
|
||||
<< VString::quoteBackslash(filename) << "\" -match \"" << trimmsg << "\"";
|
||||
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'
|
||||
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'
|
||||
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'
|
||||
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'
|
||||
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;
|
||||
`line 100 "some file" 0
|
||||
$info("aaaaaaaa");
|
||||
$info("bbbbbbbb");
|
||||
$info("aaaaaaaa file='%s'", `__FILE__);
|
||||
$info("bbbbbbbb file='%s'", `__FILE__);
|
||||
`line 200 "somefile.v" 0
|
||||
$info("cccccccc");
|
||||
$info("cccccccc file='%s'", `__FILE__);
|
||||
`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
|
||||
|
|
|
@ -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