pforth: use long for off_t
authorPhil Burk <philburk@mobileer.com>
Sun, 22 Apr 2018 18:16:20 +0000 (11:16 -0700)
committerPhil Burk <philburk@mobileer.com>
Sun, 22 Apr 2018 18:16:20 +0000 (11:16 -0700)
Check for attempt to use position values that are too large.
Remove use of fseeko() and ftello().

csrc/pf_inner.c
csrc/pf_io.c
csrc/pf_io.h

index e435d49..606dc5c 100644 (file)
@@ -1062,12 +1062,20 @@ 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 ) */
             {
                 file_offset_t offset;
         case ID_FILE_REPOSITION: /* ( ud fid -- ior ) */
             {
                 file_offset_t offset;
+                cell_t offsetHigh;
+                cell_t offsetLow;
                 FileID = (FileStream *) TOS;
                 FileID = (FileStream *) TOS;
-                offset = M_POP;
-                /* Avoid compiler warnings on Mac. */
-                offset = (sizeof(file_offset_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;
                 TOS = sdSeekFile( FileID, offset, PF_SEEK_SET );
             }
             endcase;
@@ -1075,15 +1083,21 @@ DBUG(("XX ah,m,l = 0x%8x,%8x,%8x - qh,l = 0x%8x,%8x\n", ah,am,al, qh,ql ));
         case ID_FILE_POSITION: /* ( fid -- ud ior ) */
             {
                 file_offset_t position;
         case ID_FILE_POSITION: /* ( fid -- ud ior ) */
             {
                 file_offset_t position;
-                file_offset_t offsetHi;
                 FileID = (FileStream *) TOS;
                 position = sdTellFile( FileID );
                 FileID = (FileStream *) TOS;
                 position = sdTellFile( FileID );
-                M_PUSH(position);
-                /* Just use a 0 if they are the same size. */
-                offsetHi = (sizeof(file_offset_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;
+                }
             }
             endcase;
 
             }
             endcase;
 
index 3b48d0a..ea6f4b5 100644 (file)
@@ -194,7 +194,7 @@ cell_t sdWriteFile( void *ptr, cell_t Size, int32_t nItems, FileStream * Stream
     TOUCH(Stream);
     return 0;
 }
     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);
 {
     UNIMPLEMENTED("sdSeekFile");
     TOUCH(Stream);
index 5217390..db8fd92 100644 (file)
@@ -122,14 +122,18 @@ void ioTerm( void );
         #define sdFlushFile     fflush
         #define sdReadFile      fread
         #define sdWriteFile     fwrite
         #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
         #define sdCloseFile     fclose
         #define sdRenameFile    rename
         #define sdInputChar     fgetc
@@ -141,6 +145,7 @@ void ioTerm( void );
         #define  PF_SEEK_CUR   (SEEK_CUR)
         #define  PF_SEEK_END   (SEEK_END)
 
         #define  PF_SEEK_CUR   (SEEK_CUR)
         #define  PF_SEEK_END   (SEEK_END)
 
+        /* TODO review the Size data type. */
         ThrowCode sdResizeFile( FileStream *, uint64_t Size);
 
         /*
         ThrowCode sdResizeFile( FileStream *, uint64_t Size);
 
         /*