Skip to content
6 changes: 4 additions & 2 deletions src/wfpak.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1819,11 +1819,13 @@ RC WFILE::wf_Close( // Close weather file if open
{
RC rc = RCOK;
if (yac)
{ if ( hdr // if header given
{
#if 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs comments to explain why it's #ifd out.

if ( hdr // if header given
&& yac->wrAccess() ) // and file open for write access (ie only in util programs)
// (FALSE if file not open at all)
rc = yac->write( hdr, hdrBytes, 0L, WRN); // rewrite header at start file from caller's buffer

#endif
rc |= yac->close(WRN); // close file. nop if not open. yacam.cpp.
}
if (yacTDV)
Expand Down
175 changes: 86 additions & 89 deletions src/yacam.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@

#include "cnglob.h" // CSE global definitions, data types, etc, etc.

#include <io.h> // _rtl_creat open close read
#include <fcntl.h> // O_BINARY O_RDONLY
#include <sys/stat.h> // S_IREAD, S_IWRITE

#include "msghans.h" // MH_xxxx defns: disk message text handles
#include "messages.h" // msgI: gets disk texts

Expand All @@ -38,7 +34,7 @@ void YACAM::init() // initialize -- content of c'tor, also separately callable
{
mPathName = NULL;
mWhat[0] = 0;
mFh = -1;
mFh = NULL;
mWrAccess = dirty = FALSE;
mFilSz = mFilO = -1L;
bufN = bufI = mLineNo = 0;
Expand Down Expand Up @@ -88,54 +84,14 @@ RC YACAM::open( // open file for reading, return RCOK if ok
mFilSz = -1L; // file size "unkown": only used when writing 10-94

// open file, conditionally report error
mFh = ::open( mPathName, // C library function
(wrAccess ? O_RDWR : O_RDONLY) | O_BINARY,
S_IREAD|S_IWRITE );
if (mFh < 0) // returns -1 if failed
mFh = fopen( mPathName, // C library function
(wrAccess ? "rb+" : "rb"));
if (!mFh) // returns -1 if failed
return errFl((const char *)MH_I0101); // issue message with "Cannot open" (or not) per mErOp, return RCBAD

return RCOK; // successful
} // YACAM::open
//---------------------------------------------------------------------------
RC YACAM::create( // create file to be written, return RCOK if ok
const char * pathName, // name to create. fcn fails without message if NULL.
const char * what /*="file"*/, // descriptive insert for error messages
int erOp /*=WRN*/ ) // error action: IGN no message, WRN msg & keypress, etc, above.
{
mErOp = erOp; // communicate error action to errFl

// nop if NULL pathName given
if (!pathName) return RCBAD;

// copy pathName to heap
mPathName = new char[strlen(pathName)+1];
if (!mPathName) return RCBAD; // memory full. msg?
strcpy( mPathName, pathName);

// copy 'what' to object
strncpy( mWhat, what, sizeof(mWhat)-1);
mWhat[sizeof(mWhat)-1] = '\0';

// indicate empty buffer etc
mFilO = -1L; // file offset of buffer contents: -1 indicates no buffer contents
bufN = bufI = 0;
dirty = FALSE;
//mLineNo = 1; line # used only with token-reading method

// open file, conditionally report error
mFh = ::open( mPathName, // open file. C library function.
O_CREAT|O_TRUNC|O_BINARY|O_RDWR, // create file, delete any existing contents, binary, read/write access
S_IREAD|S_IWRITE ); // read/write permission
if (mFh < 0) // returns -1 if failed
return errFl((const char *)MH_I0102); // issue message with "Cannot create" (or not) per mErOp, return RCBAD

// now have 0-length file with write access
mFilSz = 0L; // file size now 0: we just deleted any contents
mWrAccess = TRUE; // file is open with write access (as well as read access)

return RCOK; // successful
} // YACAM::create
//---------------------------------------------------------------------------
RC YACAM::close( int erOp /*=WRN*/) // close file, nop if not opened, RCOK if ok

// returns RCBAD only if file was open and an error occurred
Expand All @@ -144,11 +100,11 @@ RC YACAM::close( int erOp /*=WRN*/) // close file, nop if not opened, RCOK if ok
RC rc = RCOK; // init return code to "ok"

// if file has been opened, write buffer and close
if (mFh >= 0) // if file has been opened
if (mFh) // if file has been opened
{
rc = clrBufIf(); // if open for write, if buffer dirty, write buffer contents

if (::close(mFh) < 0) // close file -- C library function
if (mFh && fclose(mFh) != 0) // close file -- C library function
rc = errFl((const char *)MH_I0103); // conditional message containing "Close error on" / return RCBAD
}

Expand All @@ -157,7 +113,7 @@ RC YACAM::close( int erOp /*=WRN*/) // close file, nop if not opened, RCOK if ok

// clear variables
dirty = mWrAccess = FALSE;
mFh = -1;
mFh = NULL;
mFilO = mFilSz = -1L;
mPathName = NULL;
return rc;
Expand All @@ -167,8 +123,8 @@ RC YACAM::rewind([[maybe_unused]] int erOp /*=WRN*/)
// repos file to beginning
{
RC rc = clrBufIf();
if (mFh >= 0)
{ if (_lseek( mFh, 0, SEEK_SET) == -1L)
if (mFh)
{ if (fseek( mFh, 0, SEEK_SET) != 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this line hit in the tests?

rc = errFl("Seek error on");
}
mFilSz = mFilO = -1L;
Expand All @@ -180,17 +136,17 @@ RC YACAM::clrBufIf() // write buffer contents if 'dirty'.
// uses mErOp as set by caller.
{
RC rc = RCOK; // init return code to 'no error'
if ( mFh >= 0 // if file is open
if ( mFh // if file is open
&& mWrAccess // if file is open for writing
&& dirty // if buffer contains unwritten data
&& bufN ) // if buffer contains any data
{
if ( mFilO >= 0 // if have file offset for buffer contents
? _lseek( mFh, mFilO, SEEK_SET)==-1L // seek to file postition
: _lseek( mFh, 0, SEEK_END)==-1L ) // else seek to end file
? fseek( mFh, mFilO, SEEK_SET)!=0 // seek to file postition
: fseek( mFh, 0, SEEK_END)!=0 ) // else seek to end file
rc = errFl((const char *)MH_I0104); // seek failed, conditionally issue error msg containing "Seek error on"

int nw = ::write( mFh, yc_buf, bufN); // write buffer contents, return -1 or # bytes written. C library function.
int nw = fwrite( yc_buf, sizeof(char), bufN, mFh); // write buffer contents, return -1 or # bytes written. C library function.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this line hit in the tests?

if ( nw == -1 // if -1 for error
|| nw < bufN ) // if too few bytes written -- probable full disk
rc = errFl((const char *)MH_I0105); // conditionally issue message. "Write error on".
Expand Down Expand Up @@ -220,14 +176,14 @@ int YACAM::read( // read to caller's buffer

// seek if requested
if (filO >= 0L)
if (_lseek( mFh, filO, SEEK_SET)==-1L)
if (fseek( mFh, filO, SEEK_SET)!=0)
{
errFl((const char *)MH_I0104); // conditional msg. "Seek error on" 2nd use.
return -1;
}

// read
int cr = ::read( mFh, buf, count); // read bytes. C library function.
int cr = fread( buf, sizeof(char), count, mFh); // read bytes. C library function.
if (cr==-1) // returns byte count, 0 if eof, -1 if error
{
errFl((const char *)MH_I0106); // "Read error on"
Expand All @@ -240,36 +196,6 @@ int YACAM::read( // read to caller's buffer
return cr; // return # bytes read, 0 if already at EOF.
} // YACAM::read
//---------------------------------------------------------------------------
RC YACAM::write( // write from caller's buffer

char *buf, int count, // buffer address and desired number of bytes
long filO /*-1L*/, // file offset or -1L to use current position
int erOp /*=WRN*/ ) // error action: IGNore, WaRN, etc -- comments above

// random write from caller's buffer. Returns RCOK if ok.
{
mErOp = erOp; // communicate error action to errFl
if (!mWrAccess)
return errFl((const char *)MH_I0108); // cond'l msg containing "Writing to file not opened for writing:"

// seek if requested
if (filO >= 0L)
if (_lseek( mFh, filO, SEEK_SET)==-1L)
return errFl((const char *)MH_I0104); // cond'l msg containing "Seek error on" (3rd use)

// write
int cw = ::write( mFh, buf, count); // write bytes. C library function.
if ( cw==-1 // if error
|| cw < count ) // or too few bytes written (probable full disk)
return errFl((const char *)MH_I0105); // cnd'l msg containing "Write error on" (2nd use)

// update file size for possible future write-beyond-eof checking
if (filO >= 0L) // if we know where we wrote these bytes
setToMax( mFilSz, filO + count); // file size is at least write offset + count

return RCOK; // ok, all bytes written
} // YACAM::write
//---------------------------------------------------------------------------
char* YACAM::getBytes( // random access using buffer in object -- use for short, likely-to-be sequential reads.

long filO, // file offset of desired bytes
Expand Down Expand Up @@ -1040,6 +966,77 @@ RC YACAM::errFlLn( const char *s, ...) // error message "%s in <mWhat> <mPathNam
(char *)MH_I0118, // "%s '%s' (near line %d):\n %s"
mWhat, mPathName ? mPathName : "bug", mLineNo, buf );
}
#if 0 // Methonds not used, but were modified to fit c-style io, not tested. sha d06014d81f75e5ec2b9d4e31750dd0c076afae46
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Spell check
  2. Is "c-style io" the right term?
  3. Do we need the sha here? Generally we only need a sha if we're deleting something.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we settled on not putting SHAs in comments because version control systems are not forever.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's been Chip's argument for a while. I thought that if we did something like this, we'd just mention that last release version where the code appeared.

//---------------------------------------------------------------------------
RC YACAM::create( // create file to be written, return RCOK if ok
const char* pathName, // name to create. fcn fails without message if NULL.
const char* what /*="file"*/, // descriptive insert for error messages
int erOp /*=WRN*/) // error action: IGN no message, WRN msg & keypress, etc, above.
{
mErOp = erOp; // communicate error action to errFl

// nop if NULL pathName given
if (!pathName) return RCBAD;

// copy pathName to heap
mPathName = new char[strlen(pathName) + 1];
if (!mPathName) return RCBAD; // memory full. msg?
strcpy(mPathName, pathName);

// copy 'what' to object
strncpy(mWhat, what, sizeof(mWhat) - 1);
mWhat[sizeof(mWhat) - 1] = '\0';

// indicate empty buffer etc
mFilO = -1L; // file offset of buffer contents: -1 indicates no buffer contents
bufN = bufI = 0;
dirty = FALSE;
//mLineNo = 1; line # used only with token-reading method

// open file, conditionally report error
mFh = fopen(mPathName, // open file. C library function.
"wb+"); // create file, delete any existing contents, binary, read/write access

if (!mFh) // returns -1 if failed
return errFl((const char*)MH_I0102); // issue message with "Cannot create" (or not) per mErOp, return RCBAD

// now have 0-length file with write access
mFilSz = 0L; // file size now 0: we just deleted any contents
mWrAccess = TRUE; // file is open with write access (as well as read access)

return RCOK; // successful
} // YACAM::create
//---------------------------------------------------------------------------
RC YACAM::write( // write from caller's buffer

char* buf, int count, // buffer address and desired number of bytes
long filO /*-1L*/, // file offset or -1L to use current position
int erOp /*=WRN*/) // error action: IGNore, WaRN, etc -- comments above

// random write from caller's buffer. Returns RCOK if ok.
{
mErOp = erOp; // communicate error action to errFl
if (!mWrAccess)
return errFl((const char*)MH_I0108); // cond'l msg containing "Writing to file not opened for writing:"

// seek if requested
if (filO >= 0L)
if (fseek(mFh, filO, SEEK_SET) != 0)
return errFl((const char*)MH_I0104); // cond'l msg containing "Seek error on" (3rd use)

// write
int cw = fwrite(buf, sizeof(char), count, mFh); // write bytes. C library function.
if (cw == -1 // if error
|| cw < count) // or too few bytes written (probable full disk)
return errFl((const char*)MH_I0105); // cnd'l msg containing "Write error on" (2nd use)

// update file size for possible future write-beyond-eof checking
if (filO >= 0L) // if we know where we wrote these bytes
setToMax(mFilSz, filO + count); // file size is at least write offset + count

return RCOK; // ok, all bytes written
} // YACAM::write
#endif
//=============================================================================

///////////////////////////////////////////////////////////////////////////////
Expand Down
13 changes: 8 additions & 5 deletions src/yacam.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class YACAM
{ public:
char* mPathName; // pathName. We copy to heap.
char mWhat[20]; // descriptive phrase for error messages, eg "weather file"
int mFh; // file handle, or -1 if not open
FILE* mFh; // file handle, or -1 if not open
int mWrAccess; // non-0 if file open for writing
int dirty; // non-0 if buffer in object needs to be written to file
long mFilSz; // -1L or file size, for future detection of writes past end
Expand All @@ -34,19 +34,16 @@ class YACAM

// open exiting/create new file; close file; return RCOK if ok
RC open( const char * pathName, const char *what="file", int erOp=WRN, int wrAcces=FALSE);
RC create( const char * pathName, const char *what="file", int erOp=WRN);
RC close( int erOp=WRN);
RC rewind( int erOp=WRN);
RC clrBufIf(); // internal function to write buffer contents if dirty

const char* pathName() { return mPathName ? mPathName : "bug"; } // access pathName
int fh() { return mFh; } // access file handle (-1 if not open)
FILE* fh() { return mFh; } // access file handle (-1 if not open)
int wrAccess() { return mWrAccess; } // return non-0 if open to write

// random read to caller's buffer. Ret -1 if error, 0 if eof, else # bytes read (caller must check for >= count).
int read( char *buf, int count, long filO=-1L, int erOp=WRN ); // YAC_EOFOK for no message at eof or short read 10-26-94
// random write from caller's buffer, RCOK if ok
RC write( char *buf, int count, long filO=-1L, int erOp=WRN );

// random access using buffer in object -- use for short, likely-to-be sequential i/o.
char* getBytes( long filO, int count, int erOp=WRN); // returns NULL or pointer to data in buffer
Expand Down Expand Up @@ -88,6 +85,12 @@ class YACAM

int mErOp; // communicates erOp from entry points to error fcns
// note need a data mbr at end due to rcdef.exe deficiency 10-94.

#if 0 // Methonds not used, but were modified to fit c-style io, not tested. sha d06014d81f75e5ec2b9d4e31750dd0c076afae46
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comments here.

RC create(const char* pathName, const char* what = "file", int erOp = WRN);
// random write from caller's buffer, RCOK if ok
RC write(char* buf, int count, long filO = -1L, int erOp = WRN);
#endif
}; // class YACAM
//----------------------------------------------------------------------------
//-- option bits used with YACAM functions. EROPn defined in cnglob.h or notcne.h.
Expand Down