Fix %{number}s with strings. #2093.

This commit is contained in:
Wilson Snyder 2020-01-09 19:39:27 -05:00
parent 029ff69d30
commit 2a50fafef2
6 changed files with 32 additions and 9 deletions

View File

@ -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 %{number}s with strings. #2093. [agrobman]
* Verilator 4.024 2019-12-08

View File

@ -662,6 +662,7 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
case '@': { // Verilog/C++ string
va_arg(ap, int); // # bits is ignored
const std::string* cstrp = va_arg(ap, const std::string*);
if (width > cstrp->size()) output += std::string(width - cstrp->size(), ' ');
output += *cstrp;
break;
}
@ -713,13 +714,17 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
output += charval;
break;
}
case 's':
case 's': {
std::string field;
for (; lsb>=0; --lsb) {
lsb = (lsb / 8) * 8; // Next digit
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;
}
case 'd': { // Signed decimal
int digits;
std::string append;

View File

@ -496,11 +496,18 @@ bool V3Number::displayedFmtLegal(char format) {
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 {
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();
UASSERT(pos != vformat.end() && pos[0]=='%',
"$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 += ' ';
}
}
size_t fmtsizen = static_cast<size_t>(atoi(fmtsize.c_str()));
str = displayPad(fmtsizen, ' ', str);
return str;
}
case '~': // Signed decimal
@ -592,12 +601,10 @@ string V3Number::displayed(FileLine*fl, const string& vformat) const {
str = cvtToStr(toUQuad());
}
}
int intfmtsize = atoi(fmtsize.c_str());
bool zeropad = fmtsize.length()>0 && fmtsize[0]=='0';
while (static_cast<int>(str.length()) < intfmtsize) {
if (zeropad) str.insert(0, "0");
else str.insert(0, " ");
}
// fmtsize might have changed since we parsed the %fmtsize
size_t fmtsizen = static_cast<size_t>(atoi(fmtsize.c_str()));
str = displayPad(fmtsizen, (zeropad ? '0' : ' '), str);
return str;
}
case 'e':
@ -643,7 +650,9 @@ string V3Number::displayed(FileLine*fl, const string& vformat) const {
return str;
}
case '@': { // Packed string
return toString();
size_t fmtsizen = static_cast<size_t>(atoi(fmtsize.c_str()));
str = displayPad(fmtsizen, ' ', toString());
return str;
}
default:
fl->v3fatalSrc("Unknown $display-like format code for number: %"<<pos[0]);

View File

@ -175,6 +175,7 @@ private:
for (int i=0; i<words(); i++) m_value[i] = m_valueX[i] = 0;
}
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(const string& vformat) const {
return displayed(m_fileline, vformat);

View File

@ -41,6 +41,8 @@
[0] %t= 0 %03t= 0 %0t=0
[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.
hello, from a concatenated string.
hello, from a concatenated format string [0].

View File

@ -124,6 +124,10 @@ module t;
// Not testing %0s, it does different things in different simulators
$display("[%0t] %%s=%s %%s=%s %%s=%s", $time,
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,
"hel", "lo, fr", "om a very long string. Percent %s are literally substituted in.");