Support , .
This commit is contained in:
parent
d962dfe48c
commit
0703843ac1
2
Changes
2
Changes
|
|
@ -5,7 +5,7 @@ indicates the contributor was also the author of the fix; Thanks!
|
||||||
|
|
||||||
* Verilator 3.66*
|
* Verilator 3.66*
|
||||||
|
|
||||||
*** Support $feof, $fflush. [Holger Waechtler]
|
*** Support $feof, $fgetc, $fgets, $fflush. [Holger Waechtler]
|
||||||
|
|
||||||
*** Support $random.
|
*** Support $random.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,7 @@ DISTFILES_INC = $(INFOS) .gitignore COPYING *.in *.ac \
|
||||||
test_verilated/vgen*.pl \
|
test_verilated/vgen*.pl \
|
||||||
test_regress/t/*.cpp \
|
test_regress/t/*.cpp \
|
||||||
test_regress/t/*.h \
|
test_regress/t/*.h \
|
||||||
|
test_regress/t/*.dat \
|
||||||
test_regress/t/*.mem \
|
test_regress/t/*.mem \
|
||||||
test_regress/t/*.out \
|
test_regress/t/*.out \
|
||||||
test_regress/t/*.pl \
|
test_regress/t/*.pl \
|
||||||
|
|
|
||||||
|
|
@ -1554,7 +1554,7 @@ them with a $write with the appropriate format specifier.
|
||||||
|
|
||||||
The rarely used optional parameter to $finish and $stop is ignored.
|
The rarely used optional parameter to $finish and $stop is ignored.
|
||||||
|
|
||||||
=item $fopen, $fclose, $fdisplay, $feof, $fflush, $fwrite
|
=item $fopen, $fclose, $fdisplay, $feof, $fflush, $fgetc, $fgets, $fwrite
|
||||||
|
|
||||||
File descriptors passed to the file PLI calls must be file descriptors, not
|
File descriptors passed to the file PLI calls must be file descriptors, not
|
||||||
MCDs, which includes the mode parameter to $fopen being mandatory.
|
MCDs, which includes the mode parameter to $fopen being mandatory.
|
||||||
|
|
|
||||||
|
|
@ -248,6 +248,34 @@ void _VL_VINT_TO_STRING(int obits, char* destoutp, WDataInP sourcep) {
|
||||||
while (isspace(*(destp-1)) && destp>destoutp) *--destp = '\0'; // Drop trailing spaces
|
while (isspace(*(destp-1)) && destp>destoutp) *--destp = '\0'; // Drop trailing spaces
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IData VL_FGETS_IXQ(int sbits, void* strgp, QData fpq) {
|
||||||
|
FILE* fp = VL_CVT_Q_FP(fpq);
|
||||||
|
if (!fp) return 0;
|
||||||
|
|
||||||
|
// The string needs to be padded with 0's in unused spaces in front of
|
||||||
|
// any read data. This means we can't know in what location the first
|
||||||
|
// character will finally live, so we need to copy. Yuk.
|
||||||
|
IData bytes = VL_BYTES_I(sbits);
|
||||||
|
char buffer[bytes];
|
||||||
|
|
||||||
|
// We don't use fgets, as we must read \0s.
|
||||||
|
IData got = 0;
|
||||||
|
char* cp = buffer;
|
||||||
|
while (got < bytes) {
|
||||||
|
int c = getc(fp);
|
||||||
|
if (c==EOF) break;
|
||||||
|
*cp++ = c; got++;
|
||||||
|
if (c=='\n') break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to Verilog format
|
||||||
|
char* op = ((char*)(strgp));
|
||||||
|
IData i;
|
||||||
|
for (i=0; i<got; i++) { *op++ = buffer[got-1-i]; }
|
||||||
|
for (; i<bytes; i++) { *op++ = 0; }
|
||||||
|
return got;
|
||||||
|
}
|
||||||
|
|
||||||
QData VL_FOPEN_QI(QData filename, IData mode) {
|
QData VL_FOPEN_QI(QData filename, IData mode) {
|
||||||
IData fnw[2]; VL_SET_WQ(fnw, filename);
|
IData fnw[2]; VL_SET_WQ(fnw, filename);
|
||||||
return VL_FOPEN_WI(2, fnw, mode);
|
return VL_FOPEN_WI(2, fnw, mode);
|
||||||
|
|
|
||||||
|
|
@ -199,6 +199,23 @@ inline const char* VL_VALUE_FORMATTED_I(int obits, char fmt, bool drop0, IData l
|
||||||
}
|
}
|
||||||
|
|
||||||
/// File I/O
|
/// File I/O
|
||||||
|
extern IData VL_FGETS_IXQ(int sbits, void* strgp, QData fpq);
|
||||||
|
inline IData VL_FGETS_IIQ(int, int bits, int, CData& strg, QData fpq) {
|
||||||
|
return VL_FGETS_IXQ(bits, &strg, fpq);
|
||||||
|
}
|
||||||
|
inline IData VL_FGETS_IIQ(int, int bits, int, SData& strg, QData fpq) {
|
||||||
|
return VL_FGETS_IXQ(bits, &strg, fpq);
|
||||||
|
}
|
||||||
|
inline IData VL_FGETS_IIQ(int, int bits, int, IData& strg, QData fpq) {
|
||||||
|
return VL_FGETS_IXQ(bits, &strg, fpq);
|
||||||
|
}
|
||||||
|
inline IData VL_FGETS_IQQ(int, int bits, int, QData& strg, QData fpq) {
|
||||||
|
return VL_FGETS_IXQ(bits, &strg, fpq);
|
||||||
|
}
|
||||||
|
inline IData VL_FGETS_IWQ(int, int bits, int, WDataOutP strgp, QData fpq) {
|
||||||
|
return VL_FGETS_IXQ(bits, strgp, fpq);
|
||||||
|
}
|
||||||
|
|
||||||
extern QData VL_FOPEN_WI(int fnwords, WDataInP ofilename, IData mode);
|
extern QData VL_FOPEN_WI(int fnwords, WDataInP ofilename, IData mode);
|
||||||
extern QData VL_FOPEN_QI(QData ofilename, IData mode);
|
extern QData VL_FOPEN_QI(QData ofilename, IData mode);
|
||||||
inline QData VL_FOPEN_II(IData ofilename, IData mode) { return VL_FOPEN_QI(ofilename,mode); }
|
inline QData VL_FOPEN_II(IData ofilename, IData mode) { return VL_FOPEN_QI(ofilename,mode); }
|
||||||
|
|
|
||||||
|
|
@ -110,10 +110,13 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
// Integer size macros
|
// Integer size macros
|
||||||
|
|
||||||
|
#define VL_BYTESIZE 8 ///< Bits in a byte
|
||||||
#define VL_WORDSIZE 32 ///< Bits in a word
|
#define VL_WORDSIZE 32 ///< Bits in a word
|
||||||
#define VL_QUADSIZE 64 ///< Bits in a quadword
|
#define VL_QUADSIZE 64 ///< Bits in a quadword
|
||||||
#define VL_WORDSIZE_LOG2 5 ///< log2(VL_WORDSIZE)
|
#define VL_WORDSIZE_LOG2 5 ///< log2(VL_WORDSIZE)
|
||||||
|
|
||||||
|
/// Bytes this number of bits needs (1 bit=1 byte)
|
||||||
|
#define VL_BYTES_I(nbits) (((nbits)+(VL_BYTESIZE-1))/VL_BYTESIZE)
|
||||||
/// Words this number of bits needs (1 bit=1 word)
|
/// Words this number of bits needs (1 bit=1 word)
|
||||||
#define VL_WORDS_I(nbits) (((nbits)+(VL_WORDSIZE-1))/VL_WORDSIZE)
|
#define VL_WORDS_I(nbits) (((nbits)+(VL_WORDSIZE-1))/VL_WORDSIZE)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2118,6 +2118,21 @@ struct AstFEof : public AstNodeUniop {
|
||||||
AstNode* filep() const { return lhsp(); }
|
AstNode* filep() const { return lhsp(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AstFGetC : public AstNodeUniop {
|
||||||
|
AstFGetC(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {}
|
||||||
|
virtual ~AstFGetC() {}
|
||||||
|
virtual AstType type() const { return AstType::FEOF;}
|
||||||
|
virtual AstNode* clone() { return new AstFGetC(*this); }
|
||||||
|
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||||
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) { V3ERROR_NA; }
|
||||||
|
virtual string emitVerilog() { return "%k$fgetc(%l)"; }
|
||||||
|
virtual string emitOperator() { return "VL_FGETC"; }
|
||||||
|
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;}
|
||||||
|
virtual bool sizeMattersLhs() {return false;}
|
||||||
|
virtual int instrCount() const { return widthInstrs()*64; }
|
||||||
|
AstNode* filep() const { return lhsp(); }
|
||||||
|
};
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// Binary ops
|
// Binary ops
|
||||||
|
|
||||||
|
|
@ -2729,6 +2744,22 @@ struct AstReplicate : public AstNodeBiop {
|
||||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||||
virtual int instrCount() const { return widthInstrs()*2; }
|
virtual int instrCount() const { return widthInstrs()*2; }
|
||||||
};
|
};
|
||||||
|
struct AstFGetS : public AstNodeBiop {
|
||||||
|
AstFGetS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {}
|
||||||
|
virtual ~AstFGetS() {}
|
||||||
|
virtual AstType type() const { return AstType::FEOF;}
|
||||||
|
virtual AstNode* clone() { return new AstFGetS(*this); }
|
||||||
|
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||||
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { V3ERROR_NA; }
|
||||||
|
virtual string emitVerilog() { return "%k$fgets(%l,%r)"; }
|
||||||
|
virtual string emitOperator() { return "VL_FGETS"; }
|
||||||
|
virtual bool cleanOut() {return false;}
|
||||||
|
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||||
|
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||||
|
virtual int instrCount() const { return widthInstrs()*64; }
|
||||||
|
AstNode* strgp() const { return lhsp(); }
|
||||||
|
AstNode* filep() const { return rhsp(); }
|
||||||
|
};
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// SysVerilog assertions
|
// SysVerilog assertions
|
||||||
|
|
|
||||||
|
|
@ -306,6 +306,13 @@ public:
|
||||||
nodep->filep()->iterateAndNext(*this);
|
nodep->filep()->iterateAndNext(*this);
|
||||||
puts(")); ");
|
puts(")); ");
|
||||||
}
|
}
|
||||||
|
virtual void visit(AstFGetC* nodep, AstNUser*) {
|
||||||
|
puts("(");
|
||||||
|
nodep->filep()->iterateAndNext(*this);
|
||||||
|
puts("? fgetc(VL_CVT_Q_FP(");
|
||||||
|
nodep->filep()->iterateAndNext(*this);
|
||||||
|
puts(")) : -1)"); // Non-existant filehandle should return EOF
|
||||||
|
}
|
||||||
virtual void visit(AstWhile* nodep, AstNUser*) {
|
virtual void visit(AstWhile* nodep, AstNUser*) {
|
||||||
nodep->precondsp()->iterateAndNext(*this);
|
nodep->precondsp()->iterateAndNext(*this);
|
||||||
puts("while (");
|
puts("while (");
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,23 @@ private:
|
||||||
}
|
}
|
||||||
m_setRefLvalue = last_setRefLvalue;
|
m_setRefLvalue = last_setRefLvalue;
|
||||||
}
|
}
|
||||||
|
virtual void visit(AstFGetC* nodep, AstNUser*) {
|
||||||
|
bool last_setRefLvalue = m_setRefLvalue;
|
||||||
|
{
|
||||||
|
m_setRefLvalue = true;
|
||||||
|
nodep->filep()->iterateAndNext(*this);
|
||||||
|
}
|
||||||
|
m_setRefLvalue = last_setRefLvalue;
|
||||||
|
}
|
||||||
|
virtual void visit(AstFGetS* nodep, AstNUser*) {
|
||||||
|
bool last_setRefLvalue = m_setRefLvalue;
|
||||||
|
{
|
||||||
|
m_setRefLvalue = true;
|
||||||
|
nodep->filep()->iterateAndNext(*this);
|
||||||
|
nodep->strgp()->iterateAndNext(*this);
|
||||||
|
}
|
||||||
|
m_setRefLvalue = last_setRefLvalue;
|
||||||
|
}
|
||||||
virtual void visit(AstReadMem* nodep, AstNUser*) {
|
virtual void visit(AstReadMem* nodep, AstNUser*) {
|
||||||
bool last_setRefLvalue = m_setRefLvalue;
|
bool last_setRefLvalue = m_setRefLvalue;
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -332,6 +332,14 @@ private:
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
|
expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
|
||||||
}
|
}
|
||||||
|
virtual void visit(AstFGetC* nodep, AstNUser*) {
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
|
||||||
|
}
|
||||||
|
virtual void visit(AstFGetS* nodep, AstNUser*) {
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
|
||||||
|
}
|
||||||
virtual void visit(AstDisplay* nodep, AstNUser*) {
|
virtual void visit(AstDisplay* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
if (nodep->filep()) expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
|
if (nodep->filep()) expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,8 @@ private:
|
||||||
virtual void visit(AstOneHot* nodep,AstNUser*) { signed_Ou_Ix(nodep); }
|
virtual void visit(AstOneHot* nodep,AstNUser*) { signed_Ou_Ix(nodep); }
|
||||||
virtual void visit(AstOneHot0* nodep,AstNUser*) { signed_Ou_Ix(nodep); }
|
virtual void visit(AstOneHot0* nodep,AstNUser*) { signed_Ou_Ix(nodep); }
|
||||||
virtual void visit(AstFEof* nodep, AstNUser*) { signed_Ou_Ix(nodep); }
|
virtual void visit(AstFEof* nodep, AstNUser*) { signed_Ou_Ix(nodep); }
|
||||||
|
virtual void visit(AstFGetC* nodep, AstNUser*) { signed_Ou_Ix(nodep); }
|
||||||
|
virtual void visit(AstFGetS* nodep, AstNUser*) { signed_Ou_Ix(nodep); }
|
||||||
//
|
//
|
||||||
virtual void visit(AstConcat* nodep, AstNUser*) { signed_Ou_Ix(nodep); }
|
virtual void visit(AstConcat* nodep, AstNUser*) { signed_Ou_Ix(nodep); }
|
||||||
virtual void visit(AstReplicate* nodep, AstNUser*) { signed_Ou_Ix(nodep); }
|
virtual void visit(AstReplicate* nodep, AstNUser*) { signed_Ou_Ix(nodep); }
|
||||||
|
|
|
||||||
|
|
@ -576,12 +576,25 @@ private:
|
||||||
nodep->filep()->iterateAndNext(*this,WidthVP(64,64,BOTH).p());
|
nodep->filep()->iterateAndNext(*this,WidthVP(64,64,BOTH).p());
|
||||||
}
|
}
|
||||||
virtual void visit(AstFEof* nodep, AstNUser*) {
|
virtual void visit(AstFEof* nodep, AstNUser*) {
|
||||||
nodep->lhsp()->iterateAndNext(*this,WidthVP(64,64,BOTH).p());
|
nodep->filep()->iterateAndNext(*this,WidthVP(64,64,BOTH).p());
|
||||||
nodep->width(1,1);
|
nodep->width(1,1);
|
||||||
}
|
}
|
||||||
virtual void visit(AstFFlush* nodep, AstNUser*) {
|
virtual void visit(AstFFlush* nodep, AstNUser*) {
|
||||||
nodep->filep()->iterateAndNext(*this,WidthVP(64,64,BOTH).p());
|
nodep->filep()->iterateAndNext(*this,WidthVP(64,64,BOTH).p());
|
||||||
}
|
}
|
||||||
|
virtual void visit(AstFGetC* nodep, AstNUser* vup) {
|
||||||
|
nodep->filep()->iterateAndNext(*this,WidthVP(64,64,BOTH).p());
|
||||||
|
if (vup->c()->prelim()) {
|
||||||
|
nodep->width(32,8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtual void visit(AstFGetS* nodep, AstNUser* vup) {
|
||||||
|
nodep->filep()->iterateAndNext(*this,WidthVP(64,64,BOTH).p());
|
||||||
|
nodep->strgp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||||
|
if (vup->c()->prelim()) {
|
||||||
|
nodep->width(32,32);
|
||||||
|
}
|
||||||
|
}
|
||||||
virtual void visit(AstReadMem* nodep, AstNUser*) {
|
virtual void visit(AstReadMem* nodep, AstNUser*) {
|
||||||
nodep->filenamep()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
nodep->filenamep()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||||
nodep->memp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
nodep->memp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||||
|
|
|
||||||
|
|
@ -134,6 +134,8 @@ escid \\[^ \t\f\r\n]+
|
||||||
"$fdisplay" {yylval.fileline = CRELINE(); return yD_FDISPLAY;}
|
"$fdisplay" {yylval.fileline = CRELINE(); return yD_FDISPLAY;}
|
||||||
"$feof" {yylval.fileline = CRELINE(); return yD_FEOF;}
|
"$feof" {yylval.fileline = CRELINE(); return yD_FEOF;}
|
||||||
"$fflush" {yylval.fileline = CRELINE(); return yD_FFLUSH;}
|
"$fflush" {yylval.fileline = CRELINE(); return yD_FFLUSH;}
|
||||||
|
"$fgetc" {yylval.fileline = CRELINE(); return yD_FGETC;}
|
||||||
|
"$fgets" {yylval.fileline = CRELINE(); return yD_FGETS;}
|
||||||
"$finish" {yylval.fileline = CRELINE(); return yD_FINISH;}
|
"$finish" {yylval.fileline = CRELINE(); return yD_FINISH;}
|
||||||
"$fopen" {yylval.fileline = CRELINE(); return yD_FOPEN;}
|
"$fopen" {yylval.fileline = CRELINE(); return yD_FOPEN;}
|
||||||
"$fullskew" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;}
|
"$fullskew" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;}
|
||||||
|
|
|
||||||
|
|
@ -228,6 +228,8 @@ class AstSenTree;
|
||||||
%token<fileline> yD_FDISPLAY "$fdisplay"
|
%token<fileline> yD_FDISPLAY "$fdisplay"
|
||||||
%token<fileline> yD_FEOF "$feof"
|
%token<fileline> yD_FEOF "$feof"
|
||||||
%token<fileline> yD_FFLUSH "$fflush"
|
%token<fileline> yD_FFLUSH "$fflush"
|
||||||
|
%token<fileline> yD_FGETC "$fgetc"
|
||||||
|
%token<fileline> yD_FGETS "$fgets"
|
||||||
%token<fileline> yD_FINISH "$finish"
|
%token<fileline> yD_FINISH "$finish"
|
||||||
%token<fileline> yD_FOPEN "$fopen"
|
%token<fileline> yD_FOPEN "$fopen"
|
||||||
%token<fileline> yD_FWRITE "$fwrite"
|
%token<fileline> yD_FWRITE "$fwrite"
|
||||||
|
|
@ -1083,6 +1085,8 @@ exprNoStr: expr yP_OROR expr { $$ = new AstLogOr ($2,$1,$3); }
|
||||||
| yD_CLOG2 '(' expr ')' { $$ = new AstCLog2($1,$3); }
|
| yD_CLOG2 '(' expr ')' { $$ = new AstCLog2($1,$3); }
|
||||||
| yD_COUNTONES '(' expr ')' { $$ = new AstCountOnes($1,$3); }
|
| yD_COUNTONES '(' expr ')' { $$ = new AstCountOnes($1,$3); }
|
||||||
| yD_FEOF '(' expr ')' { $$ = new AstFEof($1,$3); }
|
| yD_FEOF '(' expr ')' { $$ = new AstFEof($1,$3); }
|
||||||
|
| yD_FGETC '(' expr ')' { $$ = new AstFGetC($1,$3); }
|
||||||
|
| yD_FGETS '(' varRefDotBit ',' expr ')' { $$ = new AstFGetS($1,$3,$5); }
|
||||||
| yD_ISUNKNOWN '(' expr ')' { $$ = new AstIsUnknown($1,$3); }
|
| yD_ISUNKNOWN '(' expr ')' { $$ = new AstIsUnknown($1,$3); }
|
||||||
| yD_ONEHOT '(' expr ')' { $$ = new AstOneHot($1,$3); }
|
| yD_ONEHOT '(' expr ')' { $$ = new AstOneHot($1,$3); }
|
||||||
| yD_ONEHOT0 '(' expr ')' { $$ = new AstOneHot0($1,$3); }
|
| yD_ONEHOT0 '(' expr ')' { $$ = new AstOneHot0($1,$3); }
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,11 @@
|
||||||
module t;
|
module t;
|
||||||
`verilator_file_descriptor file;
|
`verilator_file_descriptor file;
|
||||||
|
|
||||||
|
integer chars;
|
||||||
|
reg [1*8:1] letterl;
|
||||||
|
reg [8*8:1] letterq;
|
||||||
|
reg [16*8:1] letterw;
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
// Display formatting
|
// Display formatting
|
||||||
`ifdef verilator
|
`ifdef verilator
|
||||||
|
|
@ -30,6 +35,7 @@ module t;
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
// Check for opening errors
|
||||||
file = $fopen("obj_dir/DOES_NOT_EXIST","r"); // The "r" is required so we get a FD not a MFD
|
file = $fopen("obj_dir/DOES_NOT_EXIST","r"); // The "r" is required so we get a FD not a MFD
|
||||||
if (|file) $stop; // Should not exist, IE must return 0
|
if (|file) $stop; // Should not exist, IE must return 0
|
||||||
end
|
end
|
||||||
|
|
@ -40,6 +46,37 @@ module t;
|
||||||
$fclose(file);
|
$fclose(file);
|
||||||
end
|
end
|
||||||
|
|
||||||
|
begin
|
||||||
|
// Check read functions
|
||||||
|
file = $fopen("t/t_sys_file_input.dat","r");
|
||||||
|
if ($feof(file)) $stop;
|
||||||
|
|
||||||
|
// $fgetc
|
||||||
|
if ($fgetc(file) != "h") $stop;
|
||||||
|
if ($fgetc(file) != "i") $stop;
|
||||||
|
if ($fgetc(file) != "\n") $stop;
|
||||||
|
|
||||||
|
// $fgets
|
||||||
|
chars = $fgets(letterl, file);
|
||||||
|
$write("c=%0d l=%s\n", chars, letterl);
|
||||||
|
if (chars != 1) $stop;
|
||||||
|
if (letterl != "l") $stop;
|
||||||
|
|
||||||
|
chars = $fgets(letterq, file);
|
||||||
|
$write("c=%0d q=%x=%s", chars, letterq, letterq); // Output includes newline
|
||||||
|
if (chars != 5) $stop;
|
||||||
|
if (letterq != "\0\0\0quad\n") $stop;
|
||||||
|
|
||||||
|
letterw = "5432109876543210";
|
||||||
|
chars = $fgets(letterw, file);
|
||||||
|
$write("c=%0d w=%s", chars, letterw); // Output includes newline
|
||||||
|
if (chars != 10) $stop;
|
||||||
|
if (letterw != "\0\0\0\0\0\0widestuff\n") $stop;
|
||||||
|
|
||||||
|
$fclose(file);
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
$write("*-* All Finished *-*\n");
|
$write("*-* All Finished *-*\n");
|
||||||
$finish(0); // Test arguments to finish
|
$finish(0); // Test arguments to finish
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
hi
|
||||||
|
lquad
|
||||||
|
widestuff
|
||||||
Loading…
Reference in New Issue