Support with non-format arguments, bug467.

Signed-off-by: Wilson Snyder <wsnyder@wsnyder.org>
This commit is contained in:
Jamey Hicks 2015-10-27 20:58:31 -04:00 committed by Wilson Snyder
parent 4475060268
commit 49108c23f0
7 changed files with 67 additions and 5 deletions

View File

@ -13,6 +13,8 @@ indicates the contributor was also the author of the fix; Thanks!
*** Support elaboration assertions, bug973. [Johan Bjork]
*** Support $display with non-format arguments, bug467. [Jamey Hicks]
**** Add VerilatedScopeNameMap for introspection, bug966. [Todd Strader]
**** Ignore %l in $display, bug983. [Todd Strader]

View File

@ -254,7 +254,7 @@ private:
}
}
void expectFormat(AstNode* nodep, const string& format, AstNode* argp, bool isScan) {
string expectFormat(AstNode* nodep, const string& format, AstNode* argp, bool isScan) {
// Check display arguments
bool inPct = false;
for (string::const_iterator it = format.begin(); it != format.end(); ++it) {
@ -290,8 +290,57 @@ private:
} // switch
}
}
if (argp) {
argp->v3error("Extra arguments for $display-like format");
if (argp && !isScan) {
int skipCount = 0; // number of args consume by any additional format strings
string newFormat(format);
while (argp) {
if (skipCount) {
argp = argp->nextp();
skipCount--;
continue;
}
AstConst *constp = argp->castConst();
bool isFromString = (constp) ? constp->num().isFromString() : false;
if (isFromString) {
int numchars = argp->dtypep()->width()/8;
string str(numchars, ' ');
// now scan for % operators
bool inpercent = false;
for (int i = 0; i < numchars; i++) {
int ii = numchars - i - 1;
char c = constp->num().dataByte(ii);
str[i] = c;
if (!inpercent && c == '%') {
inpercent = true;
} else if (inpercent) {
inpercent = 0;
switch (c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case '.':
inpercent = true;
break;
case '%':
break;
default:
if (V3Number::displayedFmtLegal(c)) {
skipCount++;
}
}
}
}
newFormat.append(str);
AstNode *nextp = argp->nextp();
argp->unlinkFrBack(); pushDeletep(argp); VL_DANGLING(argp);
argp = nextp;
} else {
newFormat.append("%h");
argp = argp->nextp();
}
}
return newFormat;
} else {
return string();
}
}
@ -322,7 +371,9 @@ private:
}
virtual void visit(AstSFormatF* nodep, AstNUser*) {
nodep->iterateChildren(*this);
expectFormat(nodep, nodep->text(), nodep->exprsp(), false);
string newFormat = expectFormat(nodep, nodep->text(), nodep->exprsp(), false);
if (newFormat.size())
nodep->text(newFormat);
if ((nodep->backp()->castDisplay() && nodep->backp()->castDisplay()->displayType().needScopeTracking())
|| nodep->formatScopeTracking()) {
nodep->scopeNamep(new AstScopeName(nodep->fileline()));

View File

@ -205,6 +205,7 @@ public:
double toDouble() const;
uint32_t toHash() const;
uint32_t dataWord(int word) const;
uint8_t dataByte(int byte) const { return (dataWord(byte/4) >> (8*(byte&3))) & 0xff; }
uint32_t countOnes() const;
uint32_t mostSetBitP1() const; // Highest bit set plus one, IE for 16 return 5, for 0 return 0.

View File

@ -28,6 +28,9 @@ execute (
[0] %s=! %s= what! %s= hmmm!1234
[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].
extra argument: 0000000000000000
[0] Embedded <#013> return
[0] Embedded
multiline

View File

@ -43,6 +43,9 @@ module t;
$display("[%0t] %s%s%s", $time,
"hel", "lo, fr", "om a very long string. Percent %s are literally substituted in.");
$display("hel", "lo, fr", "om a concatenated string.");
$write("hel", "lo, fr", "om a concatenated format string [%0t].\n", $time);
$display("extra argument: ", $time);
$write("[%0t] Embedded \r return\n", $time);
$display("[%0t] Embedded\
multiline", $time);

View File

@ -12,7 +12,6 @@ compile (
fails=>1,
expect=>
'%Error: t/t_display_bad.v:\d+: Missing arguments for \$display-like format
%Error: t/t_display_bad.v:\d+: Extra arguments for \$display-like format
%Error: t/t_display_bad.v:\d+: Unknown \$display-like format code: %q
%Error: Exiting due to.*',
);

View File

@ -31,6 +31,9 @@ execute (
[0] %s=! %s= what! %s= hmmm!1234
[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].
extra argument: 0000000000000000
[0] Embedded <#013> return
[0] Embedded
multiline