relicense to 0BSD
[pforth] / csrc / pf_inner.c
index 2e5aac6..fc1d7e4 100644 (file)
@@ -5,14 +5,17 @@
 ** Author: Phil Burk
 ** Copyright 1994 3DO, Phil Burk, Larry Polansky, David Rosenboom
 **
 ** Author: Phil Burk
 ** Copyright 1994 3DO, Phil Burk, Larry Polansky, David Rosenboom
 **
-** The pForth software code is dedicated to the public domain,
-** and any third party may reproduce, distribute and modify
-** the pForth software code or any derivative works thereof
-** without any compensation or license.  The pForth software
-** code is provided on an "as is" basis without any warranty
-** of any kind, including, without limitation, the implied
-** warranties of merchantability and fitness for a particular
-** purpose and their equivalents under the laws of any jurisdiction.
+** Permission to use, copy, modify, and/or distribute this
+** software for any purpose with or without fee is hereby granted.
+**
+** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+** THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
+** CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+** FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+** CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+** OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 **
 ****************************************************************
 **
 **
 ****************************************************************
 **
 **
 ***************************************************************/
 
 **
 ***************************************************************/
 
-#ifndef AMIGA
-#include <sys/types.h>
-#else
-typedef long off_t;
-#endif
-
 #include "pf_all.h"
 
 #if defined(WIN32) && !defined(__MINGW32__)
 #include "pf_all.h"
 
 #if defined(WIN32) && !defined(__MINGW32__)
@@ -55,6 +52,7 @@ typedef long off_t;
 #define M_DUP    PUSH_TOS;
 #define M_DROP   { TOS = M_POP; }
 
 #define M_DUP    PUSH_TOS;
 #define M_DROP   { TOS = M_POP; }
 
+#define ASCII_EOT   (0x04)
 
 /***************************************************************
 ** Macros for Floating Point stack access.
 
 /***************************************************************
 ** Macros for Floating Point stack access.
@@ -203,8 +201,8 @@ static void TraceNames( ExecToken Token, cell_t Level )
 static uint64_t UdToUint64( ucell_t Lo, ucell_t Hi )
 {
     return (( 2 * sizeof(ucell_t) == sizeof(uint64_t) )
 static uint64_t UdToUint64( ucell_t Lo, ucell_t Hi )
 {
     return (( 2 * sizeof(ucell_t) == sizeof(uint64_t) )
-           ? (((uint64_t)Lo) | (((uint64_t)Hi) >> (sizeof(ucell_t) * 8)))
-           : Lo );
+        ? (((uint64_t)Lo) | (((uint64_t)Hi) >> (sizeof(ucell_t) * 8)))
+        : Lo);
 }
 
 /* Return TRUE if the unsigned double cell integer LO/HI is not greater
 }
 
 /* Return TRUE if the unsigned double cell integer LO/HI is not greater
@@ -213,15 +211,15 @@ static uint64_t UdToUint64( ucell_t Lo, ucell_t Hi )
 static int UdIsUint64( ucell_t Lo, ucell_t Hi )
 {
     return (( 2 * sizeof(ucell_t) == sizeof(uint64_t) )
 static int UdIsUint64( ucell_t Lo, ucell_t Hi )
 {
     return (( 2 * sizeof(ucell_t) == sizeof(uint64_t) )
-           ? TRUE
-           : Hi == 0 );
+        ? TRUE
+        : Hi == 0);
 }
 
 }
 
-static const char *pfSelectFileModeCreate( int fam );
-static const char *pfSelectFileModeOpen( int fam );
+static const char *pfSelectFileModeCreate( cell_t fam );
+static const char *pfSelectFileModeOpen( cell_t fam );
 
 /**************************************************************/
 
 /**************************************************************/
-static const char *pfSelectFileModeCreate( int fam )
+static const char *pfSelectFileModeCreate( cell_t fam )
 {
     const char *famText = NULL;
     switch( fam )
 {
     const char *famText = NULL;
     switch( fam )
@@ -246,7 +244,7 @@ static const char *pfSelectFileModeCreate( int fam )
 }
 
 /**************************************************************/
 }
 
 /**************************************************************/
-static const char *pfSelectFileModeOpen( int fam )
+static const char *pfSelectFileModeOpen( cell_t fam )
 {
     const char *famText = NULL;
     switch( fam )
 {
     const char *famText = NULL;
     switch( fam )
@@ -275,7 +273,7 @@ static const char *pfSelectFileModeOpen( int fam )
 }
 
 /**************************************************************/
 }
 
 /**************************************************************/
-int pfCatch( ExecToken XT )
+ThrowCode pfCatch( ExecToken XT )
 {
     register cell_t  TopOfStack;    /* Cache for faster execution. */
     register cell_t *DataStackPtr;
 {
     register cell_t  TopOfStack;    /* Cache for faster execution. */
     register cell_t *DataStackPtr;
@@ -508,6 +506,7 @@ DBUGX(("After Branch: IP = 0x%x\n", InsPtr ));
             endcase;
 
         case ID_BYE:
             endcase;
 
         case ID_BYE:
+            EMIT_CR;
             M_THROW( THROW_BYE );
             endcase;
 
             M_THROW( THROW_BYE );
             endcase;
 
@@ -750,8 +749,8 @@ DBUGX(("After Branch: IP = 0x%x\n", InsPtr ));
 /* Calculate product sign: */
                 sg = ((cell_t)(ahi ^ bhi) < 0);
 /* Take absolute values and reduce to um* */
 /* Calculate product sign: */
                 sg = ((cell_t)(ahi ^ bhi) < 0);
 /* Take absolute values and reduce to um* */
-                if ((cell_t)ahi < 0) ahi = (ucell_t)(-ahi);
-                if ((cell_t)bhi < 0) bhi = (ucell_t)(-bhi);
+                if ((cell_t)ahi < 0) ahi = (ucell_t)(-(cell_t)ahi);
+                if ((cell_t)bhi < 0) bhi = (ucell_t)(-(cell_t)bhi);
 
 /* Break into hi and lo 16 bit parts. */
                 alo = LOWER_HALF(ahi);
 
 /* Break into hi and lo 16 bit parts. */
                 alo = LOWER_HALF(ahi);
@@ -1035,24 +1034,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 );
             Scratch = M_POP;
             CharPtr = (char *) M_POP;
             Temp = sdReadFile( CharPtr, 1, Scratch, FileID );
+            /* TODO check feof() or ferror() */
             M_PUSH(Temp);
             TOS = 0;
             endcase;
 
             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;
             {
         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;
 
             }
             endcase;
 
@@ -1066,27 +1079,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 ) */
             {
 
         case ID_FILE_REPOSITION: /* ( ud fid -- ior ) */
             {
-                off_t offset;
+                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(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 = (file_offset_t)offsetLow;
                 TOS = sdSeekFile( FileID, offset, PF_SEEK_SET );
             }
             endcase;
 
         case ID_FILE_POSITION: /* ( fid -- ud ior ) */
             {
                 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 );
                 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;
 
             }
             endcase;
 
@@ -1239,6 +1268,9 @@ DBUG(("XX ah,m,l = 0x%8x,%8x,%8x - qh,l = 0x%8x,%8x\n", ah,am,al, qh,ql ));
         case ID_KEY:
             PUSH_TOS;
             TOS = ioKey();
         case ID_KEY:
             PUSH_TOS;
             TOS = ioKey();
+            if (TOS == ASCII_EOT) {
+                M_THROW(THROW_BYE);
+            }
             endcase;
 
 #ifndef PF_NO_SHELL
             endcase;
 
 #ifndef PF_NO_SHELL