Fix $sccanf from string, bug866.
This commit is contained in:
parent
b71b9ccb57
commit
f2a17b9b70
2
Changes
2
Changes
|
|
@ -11,6 +11,8 @@ indicates the contributor was also the author of the fix; Thanks!
|
||||||
|
|
||||||
**** Fix member select error broke in 3.868, bug867. [Iztok Jeras]
|
**** Fix member select error broke in 3.868, bug867. [Iztok Jeras]
|
||||||
|
|
||||||
|
**** Fix $sccanf from string, bug866. [David Pierce]
|
||||||
|
|
||||||
|
|
||||||
* Verilator 3.868 2014-12-20
|
* Verilator 3.868 2014-12-20
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -476,7 +476,7 @@ static inline void _vl_vsss_advance(FILE* fp, int& floc) {
|
||||||
if (fp) fgetc(fp);
|
if (fp) fgetc(fp);
|
||||||
else floc -= 8;
|
else floc -= 8;
|
||||||
}
|
}
|
||||||
static inline int _vl_vsss_peek(FILE* fp, int& floc, WDataInP fromp) {
|
static inline int _vl_vsss_peek(FILE* fp, int& floc, WDataInP fromp, const string& fstr) {
|
||||||
// Get a character without advancing
|
// Get a character without advancing
|
||||||
if (fp) {
|
if (fp) {
|
||||||
int data = fgetc(fp);
|
int data = fgetc(fp);
|
||||||
|
|
@ -486,23 +486,27 @@ static inline int _vl_vsss_peek(FILE* fp, int& floc, WDataInP fromp) {
|
||||||
} else {
|
} else {
|
||||||
if (floc < 0) return EOF;
|
if (floc < 0) return EOF;
|
||||||
floc = floc & ~7; // Align to closest character
|
floc = floc & ~7; // Align to closest character
|
||||||
int data = (fromp[VL_BITWORD_I(floc)] >> VL_BITBIT_I(floc)) & 0xff;
|
if (fromp == NULL) {
|
||||||
return data;
|
int c = fstr[fstr.length()-1 - (floc>>3)];
|
||||||
|
return fstr[fstr.length()-1 - (floc>>3)];
|
||||||
|
} else {
|
||||||
|
return (fromp[VL_BITWORD_I(floc)] >> VL_BITBIT_I(floc)) & 0xff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static inline void _vl_vsss_skipspace(FILE* fp, int& floc, WDataInP fromp) {
|
static inline void _vl_vsss_skipspace(FILE* fp, int& floc, WDataInP fromp, const string& fstr) {
|
||||||
while (1) {
|
while (1) {
|
||||||
int c = _vl_vsss_peek(fp, floc, fromp);
|
int c = _vl_vsss_peek(fp, floc, fromp, fstr);
|
||||||
if (c==EOF || !isspace(c)) return;
|
if (c==EOF || !isspace(c)) return;
|
||||||
_vl_vsss_advance(fp, floc);
|
_vl_vsss_advance(fp, floc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static inline void _vl_vsss_read(FILE* fp, int& floc, WDataInP fromp,
|
static inline void _vl_vsss_read(FILE* fp, int& floc, WDataInP fromp, const string& fstr,
|
||||||
char* tmpp, const char* acceptp) {
|
char* tmpp, const char* acceptp) {
|
||||||
// Read into tmp, consisting of characters from acceptp list
|
// Read into tmp, consisting of characters from acceptp list
|
||||||
char* cp = tmpp;
|
char* cp = tmpp;
|
||||||
while (1) {
|
while (1) {
|
||||||
int c = _vl_vsss_peek(fp, floc, fromp);
|
int c = _vl_vsss_peek(fp, floc, fromp, fstr);
|
||||||
if (c==EOF || isspace(c)) break;
|
if (c==EOF || isspace(c)) break;
|
||||||
if (acceptp!=NULL // String - allow anything
|
if (acceptp!=NULL // String - allow anything
|
||||||
&& NULL==strchr(acceptp, c)) break;
|
&& NULL==strchr(acceptp, c)) break;
|
||||||
|
|
@ -547,6 +551,7 @@ static inline void _vl_vsss_based(WDataOutP owp, int obits, int baseLog2, const
|
||||||
|
|
||||||
IData _vl_vsscanf(FILE* fp, // If a fscanf
|
IData _vl_vsscanf(FILE* fp, // If a fscanf
|
||||||
int fbits, WDataInP fromp, // Else if a sscanf
|
int fbits, WDataInP fromp, // Else if a sscanf
|
||||||
|
const string& fstr, // if a sscanf to string
|
||||||
const char* formatp, va_list ap) {
|
const char* formatp, va_list ap) {
|
||||||
// Read a Verilog $sscanf/$fscanf style format into the output list
|
// Read a Verilog $sscanf/$fscanf style format into the output list
|
||||||
// The format must be pre-processed (and lower cased) by Verilator
|
// The format must be pre-processed (and lower cased) by Verilator
|
||||||
|
|
@ -557,15 +562,15 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
|
||||||
bool inPct = false;
|
bool inPct = false;
|
||||||
const char* pos = formatp;
|
const char* pos = formatp;
|
||||||
for (; *pos && !_vl_vsss_eof(fp,floc); ++pos) {
|
for (; *pos && !_vl_vsss_eof(fp,floc); ++pos) {
|
||||||
//VL_PRINTF("_vlscan fmt='%c' floc=%d file='%c'\n", pos[0], floc, _vl_vsss_peek(fp,floc,fromp));
|
//VL_PRINTF("_vlscan fmt='%c' floc=%d file='%c'\n", pos[0], floc, _vl_vsss_peek(fp,floc,fromp,fstr));
|
||||||
if (!inPct && pos[0]=='%') {
|
if (!inPct && pos[0]=='%') {
|
||||||
inPct = true;
|
inPct = true;
|
||||||
} else if (!inPct && isspace(pos[0])) { // Format spaces
|
} else if (!inPct && isspace(pos[0])) { // Format spaces
|
||||||
while (isspace(pos[1])) pos++;
|
while (isspace(pos[1])) pos++;
|
||||||
_vl_vsss_skipspace(fp,floc,fromp);
|
_vl_vsss_skipspace(fp,floc,fromp,fstr);
|
||||||
} else if (!inPct) { // Expected Format
|
} else if (!inPct) { // Expected Format
|
||||||
_vl_vsss_skipspace(fp,floc,fromp);
|
_vl_vsss_skipspace(fp,floc,fromp,fstr);
|
||||||
int c = _vl_vsss_peek(fp,floc,fromp);
|
int c = _vl_vsss_peek(fp,floc,fromp,fstr);
|
||||||
if (c != pos[0]) goto done;
|
if (c != pos[0]) goto done;
|
||||||
else _vl_vsss_advance(fp,floc);
|
else _vl_vsss_advance(fp,floc);
|
||||||
} else { // Format character
|
} else { // Format character
|
||||||
|
|
@ -574,7 +579,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
|
||||||
char fmt = pos[0];
|
char fmt = pos[0];
|
||||||
switch (fmt) {
|
switch (fmt) {
|
||||||
case '%': {
|
case '%': {
|
||||||
int c = _vl_vsss_peek(fp,floc,fromp);
|
int c = _vl_vsss_peek(fp,floc,fromp,fstr);
|
||||||
if (c != '%') goto done;
|
if (c != '%') goto done;
|
||||||
else _vl_vsss_advance(fp,floc);
|
else _vl_vsss_advance(fp,floc);
|
||||||
break;
|
break;
|
||||||
|
|
@ -591,15 +596,15 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
|
||||||
for (int i=0; i<VL_WORDS_I(obits); i++) owp[i] = 0;
|
for (int i=0; i<VL_WORDS_I(obits); i++) owp[i] = 0;
|
||||||
switch (fmt) {
|
switch (fmt) {
|
||||||
case 'c': {
|
case 'c': {
|
||||||
int c = _vl_vsss_peek(fp,floc,fromp);
|
int c = _vl_vsss_peek(fp,floc,fromp,fstr);
|
||||||
if (c==EOF) goto done;
|
if (c==EOF) goto done;
|
||||||
else _vl_vsss_advance(fp,floc);
|
else _vl_vsss_advance(fp,floc);
|
||||||
owp[0] = c;
|
owp[0] = c;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 's': {
|
case 's': {
|
||||||
_vl_vsss_skipspace(fp,floc,fromp);
|
_vl_vsss_skipspace(fp,floc,fromp,fstr);
|
||||||
_vl_vsss_read(fp,floc,fromp, tmp, NULL);
|
_vl_vsss_read(fp,floc,fromp,fstr, tmp, NULL);
|
||||||
if (!tmp[0]) goto done;
|
if (!tmp[0]) goto done;
|
||||||
int pos = ((int)strlen(tmp))-1;
|
int pos = ((int)strlen(tmp))-1;
|
||||||
int lsb = 0;
|
int lsb = 0;
|
||||||
|
|
@ -609,8 +614,8 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'd': { // Signed decimal
|
case 'd': { // Signed decimal
|
||||||
_vl_vsss_skipspace(fp,floc,fromp);
|
_vl_vsss_skipspace(fp,floc,fromp,fstr);
|
||||||
_vl_vsss_read(fp,floc,fromp, tmp, "0123456789+-xXzZ?_");
|
_vl_vsss_read(fp,floc,fromp,fstr, tmp, "0123456789+-xXzZ?_");
|
||||||
if (!tmp[0]) goto done;
|
if (!tmp[0]) goto done;
|
||||||
vlsint64_t ld;
|
vlsint64_t ld;
|
||||||
sscanf(tmp,"%30" VL_PRI64 "d",&ld);
|
sscanf(tmp,"%30" VL_PRI64 "d",&ld);
|
||||||
|
|
@ -620,8 +625,8 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
|
||||||
case 'f':
|
case 'f':
|
||||||
case 'e':
|
case 'e':
|
||||||
case 'g': { // Real number
|
case 'g': { // Real number
|
||||||
_vl_vsss_skipspace(fp,floc,fromp);
|
_vl_vsss_skipspace(fp,floc,fromp,fstr);
|
||||||
_vl_vsss_read(fp,floc,fromp, tmp, "+-.0123456789eE");
|
_vl_vsss_read(fp,floc,fromp,fstr, tmp, "+-.0123456789eE");
|
||||||
if (!tmp[0]) goto done;
|
if (!tmp[0]) goto done;
|
||||||
union { double r; vlsint64_t ld; } u;
|
union { double r; vlsint64_t ld; } u;
|
||||||
u.r = strtod(tmp, NULL);
|
u.r = strtod(tmp, NULL);
|
||||||
|
|
@ -630,8 +635,8 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
|
||||||
}
|
}
|
||||||
case 't': // FALLTHRU // Time
|
case 't': // FALLTHRU // Time
|
||||||
case 'u': { // Unsigned decimal
|
case 'u': { // Unsigned decimal
|
||||||
_vl_vsss_skipspace(fp,floc,fromp);
|
_vl_vsss_skipspace(fp,floc,fromp,fstr);
|
||||||
_vl_vsss_read(fp,floc,fromp, tmp, "0123456789+-xXzZ?_");
|
_vl_vsss_read(fp,floc,fromp,fstr, tmp, "0123456789+-xXzZ?_");
|
||||||
if (!tmp[0]) goto done;
|
if (!tmp[0]) goto done;
|
||||||
QData ld;
|
QData ld;
|
||||||
sscanf(tmp,"%30" VL_PRI64 "u",&ld);
|
sscanf(tmp,"%30" VL_PRI64 "u",&ld);
|
||||||
|
|
@ -639,22 +644,22 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'b': {
|
case 'b': {
|
||||||
_vl_vsss_skipspace(fp,floc,fromp);
|
_vl_vsss_skipspace(fp,floc,fromp,fstr);
|
||||||
_vl_vsss_read(fp,floc,fromp, tmp, "01xXzZ?_");
|
_vl_vsss_read(fp,floc,fromp,fstr, tmp, "01xXzZ?_");
|
||||||
if (!tmp[0]) goto done;
|
if (!tmp[0]) goto done;
|
||||||
_vl_vsss_based(owp,obits, 1, tmp, 0, (int)strlen(tmp));
|
_vl_vsss_based(owp,obits, 1, tmp, 0, (int)strlen(tmp));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'o': {
|
case 'o': {
|
||||||
_vl_vsss_skipspace(fp,floc,fromp);
|
_vl_vsss_skipspace(fp,floc,fromp,fstr);
|
||||||
_vl_vsss_read(fp,floc,fromp, tmp, "01234567xXzZ?_");
|
_vl_vsss_read(fp,floc,fromp,fstr, tmp, "01234567xXzZ?_");
|
||||||
if (!tmp[0]) goto done;
|
if (!tmp[0]) goto done;
|
||||||
_vl_vsss_based(owp,obits, 3, tmp, 0, (int)strlen(tmp));
|
_vl_vsss_based(owp,obits, 3, tmp, 0, (int)strlen(tmp));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'x': {
|
case 'x': {
|
||||||
_vl_vsss_skipspace(fp,floc,fromp);
|
_vl_vsss_skipspace(fp,floc,fromp,fstr);
|
||||||
_vl_vsss_read(fp,floc,fromp, tmp, "0123456789abcdefABCDEFxXzZ?_");
|
_vl_vsss_read(fp,floc,fromp,fstr, tmp, "0123456789abcdefABCDEFxXzZ?_");
|
||||||
if (!tmp[0]) goto done;
|
if (!tmp[0]) goto done;
|
||||||
_vl_vsss_based(owp,obits, 4, tmp, 0, (int)strlen(tmp));
|
_vl_vsss_based(owp,obits, 4, tmp, 0, (int)strlen(tmp));
|
||||||
break;
|
break;
|
||||||
|
|
@ -875,7 +880,7 @@ IData VL_FSCANF_IX(IData fpi, const char* formatp, ...) {
|
||||||
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap,formatp);
|
va_start(ap,formatp);
|
||||||
IData got = _vl_vsscanf(fp, 0, NULL, formatp, ap);
|
IData got = _vl_vsscanf(fp, 0, NULL, "", formatp, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
return got;
|
return got;
|
||||||
}
|
}
|
||||||
|
|
@ -885,7 +890,7 @@ IData VL_SSCANF_IIX(int lbits, IData ld, const char* formatp, ...) {
|
||||||
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap,formatp);
|
va_start(ap,formatp);
|
||||||
IData got = _vl_vsscanf(NULL, lbits, fnw, formatp, ap);
|
IData got = _vl_vsscanf(NULL, lbits, fnw, "", formatp, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
return got;
|
return got;
|
||||||
}
|
}
|
||||||
|
|
@ -894,14 +899,21 @@ IData VL_SSCANF_IQX(int lbits, QData ld, const char* formatp, ...) {
|
||||||
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap,formatp);
|
va_start(ap,formatp);
|
||||||
IData got = _vl_vsscanf(NULL, lbits, fnw, formatp, ap);
|
IData got = _vl_vsscanf(NULL, lbits, fnw, "", formatp, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
return got;
|
return got;
|
||||||
}
|
}
|
||||||
IData VL_SSCANF_IWX(int lbits, WDataInP lwp, const char* formatp, ...) {
|
IData VL_SSCANF_IWX(int lbits, WDataInP lwp, const char* formatp, ...) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap,formatp);
|
va_start(ap,formatp);
|
||||||
IData got = _vl_vsscanf(NULL, lbits, lwp, formatp, ap);
|
IData got = _vl_vsscanf(NULL, lbits, lwp, "", formatp, ap);
|
||||||
|
va_end(ap);
|
||||||
|
return got;
|
||||||
|
}
|
||||||
|
IData VL_SSCANF_INX(int lbits, const string& ld, const char* formatp, ...) {
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap,formatp);
|
||||||
|
IData got = _vl_vsscanf(NULL, ld.length()*8, NULL, ld, formatp, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
return got;
|
return got;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ inline string VL_CVT_PACK_STR_NQ(QData lhs) {
|
||||||
IData lw[2]; VL_SET_WQ(lw, lhs);
|
IData lw[2]; VL_SET_WQ(lw, lhs);
|
||||||
return VL_CVT_PACK_STR_NW(2, lw);
|
return VL_CVT_PACK_STR_NW(2, lw);
|
||||||
}
|
}
|
||||||
inline string VL_CVT_PACK_STR_NQ(const string& lhs) {
|
inline string VL_CVT_PACK_STR_NN(const string& lhs) {
|
||||||
return lhs;
|
return lhs;
|
||||||
}
|
}
|
||||||
inline string VL_CVT_PACK_STR_NI(IData lhs) {
|
inline string VL_CVT_PACK_STR_NI(IData lhs) {
|
||||||
|
|
@ -60,6 +60,7 @@ inline string VL_REPLICATEN_NNI(int obits,int lbits,int rbits, const string& lhs
|
||||||
return VL_REPLICATEN_NNQ(obits,lbits,rbits,lhs,rep);
|
return VL_REPLICATEN_NNQ(obits,lbits,rbits,lhs,rep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern IData VL_SSCANF_INX(int lbits, const string& ld, const char* formatp, ...);
|
||||||
extern void VL_SFORMAT_X(int obits_ignored, string &output, const char* formatp, ...);
|
extern void VL_SFORMAT_X(int obits_ignored, string &output, const char* formatp, ...);
|
||||||
extern string VL_SFORMATF_NX(const char* formatp, ...);
|
extern string VL_SFORMATF_NX(const char* formatp, ...);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,9 @@ public:
|
||||||
bool emitSimpleOk(AstNodeMath* nodep);
|
bool emitSimpleOk(AstNodeMath* nodep);
|
||||||
void emitIQW(AstNode* nodep) {
|
void emitIQW(AstNode* nodep) {
|
||||||
// Other abbrevs: "C"har, "S"hort, "F"loat, "D"ouble, stri"N"g
|
// Other abbrevs: "C"har, "S"hort, "F"loat, "D"ouble, stri"N"g
|
||||||
puts (nodep->isWide()?"W":(nodep->isQuad()?"Q":"I"));
|
puts (nodep->isString() ? "N"
|
||||||
|
: nodep->isWide() ? "W"
|
||||||
|
: nodep->isQuad() ? "Q" : "I");
|
||||||
}
|
}
|
||||||
void emitScIQW(AstVar* nodep) {
|
void emitScIQW(AstVar* nodep) {
|
||||||
puts (nodep->isScBigUint() ? "SB"
|
puts (nodep->isScBigUint() ? "SB"
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ module t;
|
||||||
reg [16*8:1] letterw;
|
reg [16*8:1] letterw;
|
||||||
reg [16*8:1] letterz;
|
reg [16*8:1] letterz;
|
||||||
real r;
|
real r;
|
||||||
|
string s;
|
||||||
|
|
||||||
reg [7:0] v_a,v_b,v_c,v_d;
|
reg [7:0] v_a,v_b,v_c,v_d;
|
||||||
reg [31:0] v_worda;
|
reg [31:0] v_worda;
|
||||||
|
|
@ -131,6 +132,13 @@ module t;
|
||||||
if (r != 0.1) $stop;
|
if (r != 0.1) $stop;
|
||||||
if (letterq != 64'hfffffffffffc65a5) $stop;
|
if (letterq != 64'hfffffffffffc65a5) $stop;
|
||||||
|
|
||||||
|
s = "r=0.2 d=-236124";
|
||||||
|
chars = $sscanf(s, "r=%g d=%d", r, letterq);
|
||||||
|
if (`verbose) $write("c=%0d d=%d\n", chars, letterq);
|
||||||
|
if (chars != 2) $stop;
|
||||||
|
if (r != 0.2) $stop;
|
||||||
|
if (letterq != 64'hfffffffffffc65a4) $stop;
|
||||||
|
|
||||||
// $fscanf
|
// $fscanf
|
||||||
if ($fscanf(file,"")!=0) $stop;
|
if ($fscanf(file,"")!=0) $stop;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue