From: Phil Burk Date: Wed, 25 Apr 2018 03:24:33 +0000 (-0700) Subject: Merge pull request #44 from philburk/fix_11_off_t X-Git-Url: http://git.subgeniuskitty.com/pforth/.git/commitdiff_plain/271cd1f5a106bb0978b451457161b1df391c4c9e?hp=566edb7be0ec4eab067cae1134be69466dce0b04 Merge pull request #44 from philburk/fix_11_off_t Replace off_t with file_offset_t --- diff --git a/csrc/pf_inner.c b/csrc/pf_inner.c index 295ee55..c9b9f46 100644 --- a/csrc/pf_inner.c +++ b/csrc/pf_inner.c @@ -26,12 +26,6 @@ ** ***************************************************************/ -#ifndef AMIGA -#include -#else -typedef long off_t; -#endif - #include "pf_all.h" #if defined(WIN32) && !defined(__MINGW32__) @@ -1035,24 +1029,38 @@ DBUG(("XX ah,m,l = 0x%8x,%8x,%8x - qh,l = 0x%8x,%8x\n", ah,am,al, qh,ql )); Scratch = M_POP; CharPtr = (char *) M_POP; Temp = sdReadFile( CharPtr, 1, Scratch, FileID ); + /* TODO check feof() or ferror() */ M_PUSH(Temp); TOS = 0; endcase; + /* TODO Why does this crash when passed an illegal FID? */ case ID_FILE_SIZE: /* ( fid -- ud ior ) */ /* Determine file size by seeking to end and returning position. */ FileID = (FileStream *) TOS; { - off_t endposition, offsetHi; - off_t original = sdTellFile( FileID ); - sdSeekFile( FileID, 0, PF_SEEK_END ); - endposition = sdTellFile( FileID ); - M_PUSH(endposition); - /* Just use a 0 if they are the same size. */ - offsetHi = (sizeof(off_t) > sizeof(cell_t)) ? (endposition >> (8*sizeof(cell_t))) : 0 ; - M_PUSH(offsetHi); - sdSeekFile( FileID, original, PF_SEEK_SET ); - TOS = (original < 0) ? -4 : 0 ; /* !!! err num */ + file_offset_t endposition = -1; + file_offset_t original = sdTellFile( FileID ); + if (original >= 0) + { + sdSeekFile( FileID, 0, PF_SEEK_END ); + endposition = sdTellFile( FileID ); + /* Restore original position. */ + sdSeekFile( FileID, original, PF_SEEK_SET ); + } + if (endposition < 0) + { + M_PUSH(0); /* low */ + M_PUSH(0); /* high */ + TOS = -4; /* TODO proper error number */ + } + else + { + M_PUSH(endposition); /* low */ + /* We do not support double precision file offsets.*/ + M_PUSH(0); /* high */ + TOS = 0; /* OK */ + } } endcase; @@ -1066,27 +1074,43 @@ DBUG(("XX ah,m,l = 0x%8x,%8x,%8x - qh,l = 0x%8x,%8x\n", ah,am,al, qh,ql )); case ID_FILE_REPOSITION: /* ( ud fid -- ior ) */ { - off_t offset; + file_offset_t offset; + cell_t offsetHigh; + cell_t offsetLow; FileID = (FileStream *) TOS; - offset = M_POP; - /* Avoid compiler warnings on Mac. */ - offset = (sizeof(off_t) > sizeof(cell_t)) ? (offset << 8*sizeof(cell_t)) : 0 ; - offset += M_POP; + offsetHigh = M_POP; + offsetLow = M_POP; + /* We do not support double precision file offsets in pForth. + * So check to make sure the high bits are not used. + */ + if (offsetHigh != 0) + { + TOS = -3; /* TODO err num? */ + break; + } + offset = offsetLow; TOS = sdSeekFile( FileID, offset, PF_SEEK_SET ); } endcase; case ID_FILE_POSITION: /* ( fid -- ud ior ) */ { - off_t position; - off_t offsetHi; + file_offset_t position; FileID = (FileStream *) TOS; position = sdTellFile( FileID ); - M_PUSH(position); - /* Just use a 0 if they are the same size. */ - offsetHi = (sizeof(off_t) > sizeof(cell_t)) ? (position >> (8*sizeof(cell_t))) : 0 ; - M_PUSH(offsetHi); - TOS = (position < 0) ? -4 : 0 ; /* !!! err num */ + if (position < 0) + { + M_PUSH(0); /* low */ + M_PUSH(0); /* high */ + TOS = -4; /* TODO proper error number */ + } + else + { + M_PUSH(position); /* low */ + /* We do not support double precision file offsets.*/ + M_PUSH(0); /* high */ + TOS = 0; /* OK */ + } } endcase; diff --git a/csrc/pf_io.c b/csrc/pf_io.c index 3b48d0a..da16a14 100644 --- a/csrc/pf_io.c +++ b/csrc/pf_io.c @@ -194,7 +194,7 @@ cell_t sdWriteFile( void *ptr, cell_t Size, int32_t nItems, FileStream * Stream TOUCH(Stream); return 0; } -cell_t sdSeekFile( FileStream * Stream, cell_t Position, int32_t Mode ) +cell_t sdSeekFile( FileStream * Stream, file_offset_t Position, int32_t Mode ) { UNIMPLEMENTED("sdSeekFile"); TOUCH(Stream); @@ -202,7 +202,7 @@ cell_t sdSeekFile( FileStream * Stream, cell_t Position, int32_t Mode ) TOUCH(Mode); return 0; } -cell_t sdTellFile( FileStream * Stream ) +file_offset_t sdTellFile( FileStream * Stream ) { UNIMPLEMENTED("sdTellFile"); TOUCH(Stream); diff --git a/csrc/pf_io.h b/csrc/pf_io.h index 4576e4f..db8fd92 100644 --- a/csrc/pf_io.h +++ b/csrc/pf_io.h @@ -19,6 +19,8 @@ ** ***************************************************************/ +#include "pf_types.h" + #define PF_CHAR_XON (0x11) #define PF_CHAR_XOFF (0x13) @@ -33,7 +35,6 @@ void sdTerminalTerm( void ); void ioInit( void ); void ioTerm( void ); - #ifdef PF_NO_CHARIO void sdEnableInput( void ); void sdDisableInput( void ); @@ -84,11 +85,11 @@ void ioTerm( void ); cell_t sdFlushFile( FileStream * Stream ); cell_t sdReadFile( void *ptr, cell_t Size, int32_t nItems, FileStream * Stream ); cell_t sdWriteFile( void *ptr, cell_t Size, int32_t nItems, FileStream * Stream ); - cell_t sdSeekFile( FileStream * Stream, off_t Position, int32_t Mode ); + cell_t sdSeekFile( FileStream * Stream, file_offset_t Position, int32_t Mode ); cell_t sdRenameFile( const char *OldName, const char *NewName ); cell_t sdDeleteFile( const char *FileName ); ThrowCode sdResizeFile( FileStream *, uint64_t Size); - off_t sdTellFile( FileStream * Stream ); + file_offset_t sdTellFile( FileStream * Stream ); cell_t sdCloseFile( FileStream * Stream ); cell_t sdInputChar( FileStream *stream ); @@ -121,14 +122,18 @@ void ioTerm( void ); #define sdFlushFile fflush #define sdReadFile fread #define sdWriteFile fwrite - #if defined(WIN32) || defined(__NT__) || defined(AMIGA) - /* TODO To support 64-bit file offset we probably need fseeki64(). */ - #define sdSeekFile fseek - #define sdTellFile ftell - #else - #define sdSeekFile fseeko - #define sdTellFile ftello - #endif + + /* + * Note that fseek() and ftell() only support a long file offset. + * So 64-bit offsets may not be supported on some platforms. + * At one point we supported fseeko() and ftello() but they require + * the off_t data type, which is not very portable. + * So we decided to sacrifice vary large file support in + * favor of portability. + */ + #define sdSeekFile fseek + #define sdTellFile ftell + #define sdCloseFile fclose #define sdRenameFile rename #define sdInputChar fgetc @@ -140,6 +145,7 @@ void ioTerm( void ); #define PF_SEEK_CUR (SEEK_CUR) #define PF_SEEK_END (SEEK_END) + /* TODO review the Size data type. */ ThrowCode sdResizeFile( FileStream *, uint64_t Size); /* diff --git a/csrc/pf_types.h b/csrc/pf_types.h index ac4f33b..619a2c0 100644 --- a/csrc/pf_types.h +++ b/csrc/pf_types.h @@ -23,6 +23,13 @@ ** Type Declarations ***************************************************************/ +#ifndef AMIGA +#include +#endif + +/* file_offset_t is used in place of off_t */ +typedef long file_offset_t; + #ifndef Err typedef long Err; #endif