Add support for WATCOMC
[pforth] / csrc / pf_text.c
index ebf5c48..6d36e2c 100644 (file)
@@ -82,6 +82,8 @@ void pfReportError( const char *FunctionName, Err ErrCode )
                s = "endian-ness of dictionary does not match code";  break;\r
        case PF_ERR_FLOAT_CONFLICT & 0xFF:\r
                s = "float support mismatch between .dic file and code";  break;\r
                s = "endian-ness of dictionary does not match code";  break;\r
        case PF_ERR_FLOAT_CONFLICT & 0xFF:\r
                s = "float support mismatch between .dic file and code";  break;\r
+       case PF_ERR_CELL_SIZE_CONFLICT & 0xFF:\r
+               s = "cell size mismatch between .dic file and code";  break;\r
        default:\r
                s = "unrecognized error code!"; break;\r
        }\r
        default:\r
                s = "unrecognized error code!"; break;\r
        }\r
@@ -133,11 +135,16 @@ void pfReportThrow( ThrowCode code )
 ** Copy a Forth String to a 'C' string.\r
 */\r
 \r
 ** Copy a Forth String to a 'C' string.\r
 */\r
 \r
-char *ForthStringToC( char *dst, const char *FString )\r
+char *ForthStringToC( char *dst, const char *FString, cell_t dstSize )\r
 {\r
 {\r
-       int32 Len;\r
+       cell_t Len;\r
 \r
 \r
-       Len = (int32) *FString;\r
+       Len = (cell_t) *FString;\r
+       /* Make sure the text + NUL can fit. */\r
+       if( Len >= dstSize )\r
+       {\r
+               Len = dstSize - 1;\r
+       }\r
        pfCopyMemory( dst, FString+1, Len );\r
        dst[Len] = '\0';\r
 \r
        pfCopyMemory( dst, FString+1, Len );\r
        dst[Len] = '\0';\r
 \r
@@ -147,17 +154,20 @@ char *ForthStringToC( char *dst, const char *FString )
 /**************************************************************\r
 ** Copy a NUL terminated string to a Forth counted string.\r
 */\r
 /**************************************************************\r
 ** Copy a NUL terminated string to a Forth counted string.\r
 */\r
-char *CStringToForth( char *dst, const char *CString )\r
+char *CStringToForth( char *dst, const char *CString, cell_t dstSize )\r
 {\r
 {\r
-       char *s;\r
-       int32 i;\r
+       cell_t i;\r
 \r
 \r
-       s = dst+1;\r
-       for( i=0; *CString; i++ )\r
+       /* Make sure the SIZE+text can fit. */\r
+       for( i=1; i<dstSize; i++ )\r
        {\r
        {\r
-               *s++ = *CString++;\r
+               if( *CString == 0 )\r
+               {\r
+                       break;\r
+               }\r
+               dst[i] = *CString++;\r
        }\r
        }\r
-       *dst = (char ) i;\r
+       *dst = (char ) i-1;\r
        return dst;\r
 }\r
 \r
        return dst;\r
 }\r
 \r
@@ -165,9 +175,9 @@ char *CStringToForth( char *dst, const char *CString )
 ** Compare two test strings, case sensitive.\r
 ** Return TRUE if they match.\r
 */\r
 ** Compare two test strings, case sensitive.\r
 ** Return TRUE if they match.\r
 */\r
-int32 ffCompareText( const char *s1, const char *s2, int32 len )\r
+cell_t ffCompareText( const char *s1, const char *s2, cell_t len )\r
 {\r
 {\r
-       int32 i, Result;\r
+       cell_t i, Result;\r
        \r
        Result = TRUE;\r
        for( i=0; i<len; i++ )\r
        \r
        Result = TRUE;\r
        for( i=0; i<len; i++ )\r
@@ -187,9 +197,9 @@ DBUGX(("ffCompareText: return 0x%x\n", Result ));
 ** Compare two test strings, case INsensitive.\r
 ** Return TRUE if they match.\r
 */\r
 ** Compare two test strings, case INsensitive.\r
 ** Return TRUE if they match.\r
 */\r
-int32 ffCompareTextCaseN( const char *s1, const char *s2, int32 len )\r
+cell_t ffCompareTextCaseN( const char *s1, const char *s2, cell_t len )\r
 {\r
 {\r
-       int32 i, Result;\r
+       cell_t i, Result;\r
        char  c1,c2;\r
        \r
        Result = TRUE;\r
        char  c1,c2;\r
        \r
        Result = TRUE;\r
@@ -212,9 +222,9 @@ DBUGX(("ffCompareText: return 0x%x\n", Result ));
 ** Compare two strings, case sensitive.\r
 ** Return zero if they match, -1 if s1<s2, +1 is s1>s2;\r
 */\r
 ** Compare two strings, case sensitive.\r
 ** Return zero if they match, -1 if s1<s2, +1 is s1>s2;\r
 */\r
-int32 ffCompare( const char *s1, int32 len1, const char *s2, int32 len2 )\r
+cell_t ffCompare( const char *s1, cell_t len1, const char *s2, int32_t len2 )\r
 {\r
 {\r
-       int32 i, result, n, diff;\r
+       cell_t i, result, n, diff;\r
        \r
        result = 0;\r
        n = MIN(len1,len2);\r
        \r
        result = 0;\r
        n = MIN(len1,len2);\r
@@ -243,15 +253,15 @@ int32 ffCompare( const char *s1, int32 len1, const char *s2, int32 len2 )
 /***************************************************************\r
 ** Convert number to text.\r
 */\r
 /***************************************************************\r
 ** Convert number to text.\r
 */\r
-#define CNTT_PAD_SIZE ((sizeof(int32)*8)+2)  /* PLB 19980522 - Expand PAD so "-1 binary .s" doesn't crash. */\r
+#define CNTT_PAD_SIZE ((sizeof(cell_t)*8)+2)  /* PLB 19980522 - Expand PAD so "-1 binary .s" doesn't crash. */\r
 static char cnttPad[CNTT_PAD_SIZE];\r
 \r
 static char cnttPad[CNTT_PAD_SIZE];\r
 \r
-char *ConvertNumberToText( int32 Num, int32 Base, int32 IfSigned, int32 MinChars )\r
+char *ConvertNumberToText( cell_t Num, cell_t Base, int32_t IfSigned, int32_t MinChars )\r
 {\r
 {\r
-       int32 IfNegative = 0;\r
+       cell_t IfNegative = 0;\r
        char *p,c;\r
        char *p,c;\r
-       uint32 NewNum, Rem, uNum;\r
-       int32 i = 0;\r
+       ucell_t NewNum, Rem, uNum;\r
+       cell_t i = 0;\r
        \r
        uNum = Num;\r
        if( IfSigned )\r
        \r
        uNum = Num;\r
        if( IfSigned )\r
@@ -287,9 +297,9 @@ char *ConvertNumberToText( int32 Num, int32 Base, int32 IfSigned, int32 MinChars
 /***************************************************************\r
 ** Diagnostic routine that prints memory in table format.\r
 */\r
 /***************************************************************\r
 ** Diagnostic routine that prints memory in table format.\r
 */\r
-void DumpMemory( void *addr, int32 cnt)\r
+void DumpMemory( void *addr, cell_t cnt)\r
 {\r
 {\r
-       int32 ln, cn, nlines;\r
+       cell_t ln, cn, nlines;\r
        unsigned char *ptr, *cptr, c;\r
 \r
        nlines = (cnt + 15) / 16;\r
        unsigned char *ptr, *cptr, c;\r
 \r
        nlines = (cnt + 15) / 16;\r
@@ -300,12 +310,12 @@ void DumpMemory( void *addr, int32 cnt)
        \r
        for (ln=0; ln<nlines; ln++)\r
        {\r
        \r
        for (ln=0; ln<nlines; ln++)\r
        {\r
-               MSG( ConvertNumberToText( (int32) ptr, 16, FALSE, 8 ) );\r
+               MSG( ConvertNumberToText( (cell_t) ptr, 16, FALSE, 8 ) );\r
                MSG(": ");\r
                cptr = ptr;\r
                for (cn=0; cn<16; cn++)\r
                {\r
                MSG(": ");\r
                cptr = ptr;\r
                for (cn=0; cn<16; cn++)\r
                {\r
-                       MSG( ConvertNumberToText( (int32) *cptr++, 16, FALSE, 2 ) );\r
+                       MSG( ConvertNumberToText( (cell_t) *cptr++, 16, FALSE, 2 ) );\r
                        EMIT(' ');\r
                }\r
                EMIT(' ');\r
                        EMIT(' ');\r
                }\r
                EMIT(' ');\r
@@ -324,7 +334,7 @@ void DumpMemory( void *addr, int32 cnt)
 void TypeName( const char *Name )\r
 {\r
        const char *FirstChar;\r
 void TypeName( const char *Name )\r
 {\r
        const char *FirstChar;\r
-       int32 Len;\r
+       cell_t Len;\r
        \r
        FirstChar = Name+1;\r
        Len = *Name & 0x1F;\r
        \r
        FirstChar = Name+1;\r
        Len = *Name & 0x1F;\r
@@ -333,3 +343,65 @@ void TypeName( const char *Name )
 }\r
 \r
 \r
 }\r
 \r
 \r
+\r
+#ifdef PF_UNIT_TEST\r
+/* Unit test for string conversion routines. */\r
+#define ASSERT_PAD_IS( index, value, msg ) \\r
+       if( pad[index] != ((char)(value)) ) \\r
+       { \\r
+               ERR(( "ERROR text test failed: " msg "\n")); \\r
+               numErrors += 1; \\r
+       } \\r
+\r
+cell_t pfUnitTestText( void )\r
+{\r
+       cell_t numErrors = 0;\r
+       char pad[16];\r
+       char fpad[8];\r
+\r
+       /* test CStringToForth */\r
+       pfSetMemory(pad,0xA5,sizeof(pad));\r
+       CStringToForth( pad, "frog", 6 );\r
+       ASSERT_PAD_IS( 0, 4, "CS len 6" );\r
+       ASSERT_PAD_IS( 4, 'g', "CS end 6" );\r
+       ASSERT_PAD_IS( 5, 0xA5, "CS past 6" );\r
+       \r
+       pfSetMemory(pad,0xA5,sizeof(pad));\r
+       CStringToForth( pad, "frog", 5 );\r
+       ASSERT_PAD_IS( 0, 4, "CS len 5" );\r
+       ASSERT_PAD_IS( 4, 'g', "CS end 5" );\r
+       ASSERT_PAD_IS( 5, 0xA5, "CS past 5" );\r
+       \r
+       pfSetMemory(pad,0xA5,sizeof(pad));\r
+       CStringxxxxxToForth( pad, "frog", 4 );\r
+       ASSERT_PAD_IS( 0, 3, "CS len 4" );\r
+       ASSERT_PAD_IS( 3, 'o', "CS end 4" );\r
+       ASSERT_PAD_IS( 4, 0xA5, "CS past 4" );\r
+       \r
+       /* Make a Forth string for testing ForthStringToC. */\r
+       CStringToForth( fpad, "frog", sizeof(fpad) );\r
+       \r
+       pfSetMemory(pad,0xA5,sizeof(pad));\r
+       ForthStringToC( pad, fpad, 6 );\r
+       ASSERT_PAD_IS( 0, 'f', "FS len 6" );\r
+       ASSERT_PAD_IS( 3, 'g', "FS end 6" );\r
+       ASSERT_PAD_IS( 4, 0, "FS nul 6" );\r
+       ASSERT_PAD_IS( 5, 0xA5, "FS past 6" );\r
+       \r
+       pfSetMemory(pad,0xA5,sizeof(pad));\r
+       ForthStringToC( pad, fpad, 5 );\r
+       ASSERT_PAD_IS( 0, 'f', "FS len 5" );\r
+       ASSERT_PAD_IS( 3, 'g', "FS end 5" );\r
+       ASSERT_PAD_IS( 4, 0, "FS nul 5" );\r
+       ASSERT_PAD_IS( 5, 0xA5, "FS past 5" );\r
+       \r
+       pfSetMemory(pad,0xA5,sizeof(pad));\r
+       ForthStringToC( pad, fpad, 4 );\r
+       ASSERT_PAD_IS( 0, 'f', "FS len 4" );\r
+       ASSERT_PAD_IS( 2, 'o', "FS end 4" );\r
+       ASSERT_PAD_IS( 3, 0, "FS nul 4" );\r
+       ASSERT_PAD_IS( 4, 0xA5, "FS past 4" );\r
+       \r
+       return numErrors;\r
+}\r
+#endif\r