Skip to content

Yacam update #321

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
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