forked from github/verilator
Fix %{number}s with strings. #2093.
This commit is contained in:
parent
029ff69d30
commit
2a50fafef2
2
Changes
2
Changes
@ -36,6 +36,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
|
|||||||
|
|
||||||
**** Fix expand optimization slowing --lint-only. Closes #2091. [Thomas Watts]
|
**** Fix expand optimization slowing --lint-only. Closes #2091. [Thomas Watts]
|
||||||
|
|
||||||
|
**** Fix %{number}s with strings. #2093. [agrobman]
|
||||||
|
|
||||||
|
|
||||||
* Verilator 4.024 2019-12-08
|
* Verilator 4.024 2019-12-08
|
||||||
|
|
||||||
|
@ -662,6 +662,7 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
|
|||||||
case '@': { // Verilog/C++ string
|
case '@': { // Verilog/C++ string
|
||||||
va_arg(ap, int); // # bits is ignored
|
va_arg(ap, int); // # bits is ignored
|
||||||
const std::string* cstrp = va_arg(ap, const std::string*);
|
const std::string* cstrp = va_arg(ap, const std::string*);
|
||||||
|
if (width > cstrp->size()) output += std::string(width - cstrp->size(), ' ');
|
||||||
output += *cstrp;
|
output += *cstrp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -713,13 +714,17 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
|
|||||||
output += charval;
|
output += charval;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 's':
|
case 's': {
|
||||||
|
std::string field;
|
||||||
for (; lsb>=0; --lsb) {
|
for (; lsb>=0; --lsb) {
|
||||||
lsb = (lsb / 8) * 8; // Next digit
|
lsb = (lsb / 8) * 8; // Next digit
|
||||||
IData charval = VL_BITRSHIFT_W(lwp, lsb) & 0xff;
|
IData charval = VL_BITRSHIFT_W(lwp, lsb) & 0xff;
|
||||||
output += (charval==0)?' ':charval;
|
field += (charval==0)?' ':charval;
|
||||||
}
|
}
|
||||||
|
if (width > field.size()) output += std::string(width - field.size(), ' ');
|
||||||
|
output += field;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 'd': { // Signed decimal
|
case 'd': { // Signed decimal
|
||||||
int digits;
|
int digits;
|
||||||
std::string append;
|
std::string append;
|
||||||
|
@ -496,11 +496,18 @@ bool V3Number::displayedFmtLegal(char format) {
|
|||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string V3Number::displayPad(size_t fmtsize, char pad, const string& in) {
|
||||||
|
string prefix;
|
||||||
|
if (in.length() < fmtsize) prefix = string(fmtsize - in.length(), pad);
|
||||||
|
return prefix + in;
|
||||||
|
}
|
||||||
|
|
||||||
string V3Number::displayed(AstNode* nodep, const string& vformat) const {
|
string V3Number::displayed(AstNode* nodep, const string& vformat) const {
|
||||||
return displayed(nodep->fileline(), vformat);
|
return displayed(nodep->fileline(), vformat);
|
||||||
}
|
}
|
||||||
|
|
||||||
string V3Number::displayed(FileLine*fl, const string& vformat) const {
|
string V3Number::displayed(FileLine* fl, const string& vformat) const {
|
||||||
string::const_iterator pos = vformat.begin();
|
string::const_iterator pos = vformat.begin();
|
||||||
UASSERT(pos != vformat.end() && pos[0]=='%',
|
UASSERT(pos != vformat.end() && pos[0]=='%',
|
||||||
"$display-like function with non format argument "<<*this);
|
"$display-like function with non format argument "<<*this);
|
||||||
@ -566,6 +573,8 @@ string V3Number::displayed(FileLine*fl, const string& vformat) const {
|
|||||||
if (fmtsize != "0") str += ' ';
|
if (fmtsize != "0") str += ' ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
size_t fmtsizen = static_cast<size_t>(atoi(fmtsize.c_str()));
|
||||||
|
str = displayPad(fmtsizen, ' ', str);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
case '~': // Signed decimal
|
case '~': // Signed decimal
|
||||||
@ -592,12 +601,10 @@ string V3Number::displayed(FileLine*fl, const string& vformat) const {
|
|||||||
str = cvtToStr(toUQuad());
|
str = cvtToStr(toUQuad());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int intfmtsize = atoi(fmtsize.c_str());
|
|
||||||
bool zeropad = fmtsize.length()>0 && fmtsize[0]=='0';
|
bool zeropad = fmtsize.length()>0 && fmtsize[0]=='0';
|
||||||
while (static_cast<int>(str.length()) < intfmtsize) {
|
// fmtsize might have changed since we parsed the %fmtsize
|
||||||
if (zeropad) str.insert(0, "0");
|
size_t fmtsizen = static_cast<size_t>(atoi(fmtsize.c_str()));
|
||||||
else str.insert(0, " ");
|
str = displayPad(fmtsizen, (zeropad ? '0' : ' '), str);
|
||||||
}
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
case 'e':
|
case 'e':
|
||||||
@ -643,7 +650,9 @@ string V3Number::displayed(FileLine*fl, const string& vformat) const {
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
case '@': { // Packed string
|
case '@': { // Packed string
|
||||||
return toString();
|
size_t fmtsizen = static_cast<size_t>(atoi(fmtsize.c_str()));
|
||||||
|
str = displayPad(fmtsizen, ' ', toString());
|
||||||
|
return str;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
fl->v3fatalSrc("Unknown $display-like format code for number: %"<<pos[0]);
|
fl->v3fatalSrc("Unknown $display-like format code for number: %"<<pos[0]);
|
||||||
|
@ -175,6 +175,7 @@ private:
|
|||||||
for (int i=0; i<words(); i++) m_value[i] = m_valueX[i] = 0;
|
for (int i=0; i<words(); i++) m_value[i] = m_valueX[i] = 0;
|
||||||
}
|
}
|
||||||
void setNames(AstNode* nodep);
|
void setNames(AstNode* nodep);
|
||||||
|
static string displayPad(size_t fmtsize, char pad, const string& in);
|
||||||
string displayed(FileLine* fl, const string& vformat) const;
|
string displayed(FileLine* fl, const string& vformat) const;
|
||||||
string displayed(const string& vformat) const {
|
string displayed(const string& vformat) const {
|
||||||
return displayed(m_fileline, vformat);
|
return displayed(m_fileline, vformat);
|
||||||
|
@ -41,6 +41,8 @@
|
|||||||
[0] %t= 0 %03t= 0 %0t=0
|
[0] %t= 0 %03t= 0 %0t=0
|
||||||
|
|
||||||
[0] %s=! %s= what! %s= hmmm!1234
|
[0] %s=! %s= what! %s= hmmm!1234
|
||||||
|
[0] %6s=: !: %6s=: what!: %6s=: hmmm!1234:
|
||||||
|
[0] %8s=: sv-str:
|
||||||
[0] hello, from a very long string. Percent %s are literally substituted in.
|
[0] hello, from a very long string. Percent %s are literally substituted in.
|
||||||
hello, from a concatenated string.
|
hello, from a concatenated string.
|
||||||
hello, from a concatenated format string [0].
|
hello, from a concatenated format string [0].
|
||||||
|
@ -124,6 +124,10 @@ module t;
|
|||||||
// Not testing %0s, it does different things in different simulators
|
// Not testing %0s, it does different things in different simulators
|
||||||
$display("[%0t] %%s=%s %%s=%s %%s=%s", $time,
|
$display("[%0t] %%s=%s %%s=%s %%s=%s", $time,
|
||||||
str2[7:0], str2, str3);
|
str2[7:0], str2, str3);
|
||||||
|
$display("[%0t] %%6s=:%6s: %%6s=:%6s: %%6s=:%6s:", $time,
|
||||||
|
str2[7:0], str2, str3);
|
||||||
|
$display("[%0t] %%8s=:%8s:", $time,
|
||||||
|
svs);
|
||||||
|
|
||||||
$display("[%0t] %s%s%s", $time,
|
$display("[%0t] %s%s%s", $time,
|
||||||
"hel", "lo, fr", "om a very long string. Percent %s are literally substituted in.");
|
"hel", "lo, fr", "om a very long string. Percent %s are literally substituted in.");
|
||||||
|
Loading…
Reference in New Issue
Block a user