diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 8b9475bb52..615f1830ec 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,80 @@ 2008-12-31 13:59 UTC+0100 Foo Bar (foo.bar foobar.org) */ +2008-11-01 08:45 UTC+0200 Viktor Szakats (harbour.01 syenar hu) + * include/hbextern.ch + * common.mak + * source/rtl/Makefile + + source/rtl/hbi18n.c + + Added basic/low level i18n functions: + __I18N_SAVE( cFileName | nHandle, aSortedTable [, cComment ] ) => lSuccess + __I18N_LOAD( cFileName | nHandle ) => trs + __I18N_GETTEXT( @cText, trs ) => NIL + ; NOTE: These were originally based on Giancarlo Niccolai's work in xhb, + but everything was completely reworked, fixed, internals removed, + made portable, lighter, shorter and probably quicker. The used file + format is incompatible, slightly smaller and portable. + ; NOTE: The internal format of 'trs' (loaded translation) is also + different. For minimal memory/speed overhead, I've choosen a one + dimensional array, as opposed to the original two dimensional + (like the input aSortedTable array). + ; TODO: Higher level functions to handle selecting a default + language, loading files automatically, possibly caching + multiple loaded language translations in memory and providing + a high level HB_I18N_GETTEXT() function. We may also readd + a low-level function to create 'trs' from a memory object + instead of loading it from the disk. We should in any case make + the higher level the lightest and less app specific as possible. + + * include/hbver.ch + * source/rtl/version.c + * utils/hbtest/rt_str.prg + * ChangeLog + ! Fixed returning bit width. + * Reworked hb_version() parameter values as follows: + (also fixed some differences between docs here in the + previous entry and actual code) + HB_VERSION_HARBOUR (was: HB_V_HARBOUR ) + HB_VERSION_COMPILER (was: HB_V_COMPILER ) + HB_VERSION_MAJOR (was: HB_V_MAJOR ) + HB_VERSION_MINOR (was: HB_V_MINOR ) + HB_VERSION_MICRO (was: HB_V_REV ) + HB_VERSION_STATUS (was: HB_V_STATUS ) + HB_VERSION_REVISION (was: HB_V_COUNT ) + HB_VERSION_BLD_DATE_STR (was: HB_V_DATE_TIME ) + HB_VERSION_BLD_DATE (was: HB_V_DATE ) + HB_VERSION_BLD_TIME (was: HB_V_TIME ) + HB_VERSION_PCODE_VER (was: HB_V_PCODE ) + HB_VERSION_PCODE_VER_STR (was: HB_V_PCODE_STR ) + HB_VERSION_CHANGELOG_LAST (was: HB_V_CHANGELOG_LAST ) + HB_VERSION_CHANGELOG_REV (was: HB_V_CHANGELOG_REV ) + HB_VERSION_FLAG_PRG (was: HB_V_FLAG_HARBOUR ) + HB_VERSION_FLAG_C (was: HB_V_FLAG_C ) + HB_VERSION_FLAG_LINKER (was: HB_V_FLAG_LINKER ) + HB_VERSION_BITWIDTH (was: HB_V_BITWIDTH ) + HB_VERSION_ENDIANNESS (was: HB_V_ENDIANNESS ) + This function makes deprecated following functions: + - HB_COMPILER() => hb_version( HB_VERSION_COMPILER ) + - HB_PCODEVER() => hb_version( HB_VERSION_PCODE_VER_STR ) + - HB_BUILDDATE() => hb_version( HB_VERSION_BLD_DATE_STR ) + and macros: + - __ARCH16BIT__ + - __ARCH32BIT__ + - __ARCH64BIT__ + - __LITTLE_ENDIAN__ + - __BIG_ENDIAN__ + - __PDP_ENDIAN__ + - HB_VER_SVNID + - HB_VER_CHLID + - HB_VER_LENTRY + - HB_VER_C_USR + - HB_VER_L_USR + - HB_VER_PRG_USR + ; TOFIX: Some term anomalies regarding 'REVISION'. + + * source/vm/runner.c + * Minor formatting and added "s_" prefix to static var. + 2008-10-31 13:02 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com) * harbour/contrib/make_b32_all.bat + hbdbgfx librray for auto build. @@ -286,6 +360,10 @@ - __LITTLE_ENDIAN__ - __BIG_ENDIAN__ - __PDP_ENDIAN__ + - HB_VER_SVNID + - HB_VER_CHLID + - HB_VER_LENTRY + - HB_VER_C_USR ; NOTE: If there are no objections, I'd remove the __ARCH*BIT__ and __*ENDIAN__ predefined macros, as these can be misleading on some systems. diff --git a/harbour/common.mak b/harbour/common.mak index 271a1592b3..efd40f386d 100644 --- a/harbour/common.mak +++ b/harbour/common.mak @@ -522,6 +522,7 @@ RTL_LIB_OBJS = \ $(OBJ_DIR)\hbffind$(OBJEXT) \ $(OBJ_DIR)\hbfile$(OBJEXT) \ $(OBJ_DIR)\hbgtcore$(OBJEXT) \ + $(OBJ_DIR)\hbi18n$(OBJEXT) \ $(OBJ_DIR)\hbinet$(OBJEXT) \ $(OBJ_DIR)\hbstrsh$(OBJEXT) \ $(OBJ_DIR)\hbrandom$(OBJEXT) \ diff --git a/harbour/include/hbextern.ch b/harbour/include/hbextern.ch index 4d97f977fc..f5d6ad23a6 100644 --- a/harbour/include/hbextern.ch +++ b/harbour/include/hbextern.ch @@ -543,6 +543,10 @@ EXTERNAL __MVXRELEASE EXTERNAL __EINSTVAR52 EXTERNAL __EINSTVAR53 +EXTERNAL __I18N_SAVE +EXTERNAL __I18N_LOAD +EXTERNAL __I18N_GETTEXT + /* The debugger interface */ EXTERNAL __DBGINVOKEDEBUG diff --git a/harbour/include/hbver.ch b/harbour/include/hbver.ch index b6e7d5c4d5..6619040539 100644 --- a/harbour/include/hbver.ch +++ b/harbour/include/hbver.ch @@ -56,29 +56,29 @@ #define HB_VER_CH_ /* hb_version() parameters. */ -#define HB_V_HARBOUR 0 /* default */ -#define HB_V_COMPILER 1 -#define HB_V_VER_MAJOR 2 -#define HB_V_VER_MINOR 3 -#define HB_V_VER_REV 4 -#define HB_V_VER_STATUS 5 -#define HB_V_VER_COUNT 6 -#define HB_V_DATE_TIME 7 -#define HB_V_DATE 8 -#define HB_V_TIME 9 -#define HB_V_PCODE_VER 10 -#define HB_V_PCODE_VER_STR 11 -#define HB_V_CHANGELOG_LAST 12 -#define HB_V_CHANGELOG_REV 13 -#define HB_V_FLAG_HARBOUR 14 -#define HB_V_FLAG_C 15 -#define HB_V_FLAG_LINKER 16 -#define HB_V_BITWIDTH 17 -#define HB_V_ENDIANNESS 18 +#define HB_VERSION_HARBOUR 0 /* default */ +#define HB_VERSION_COMPILER 1 +#define HB_VERSION_MAJOR 2 +#define HB_VERSION_MINOR 3 +#define HB_VERSION_MICRO 4 +#define HB_VERSION_STATUS 5 +#define HB_VERSION_REVISION 6 +#define HB_VERSION_BLD_DATE_STR 7 +#define HB_VERSION_BLD_DATE 8 +#define HB_VERSION_BLD_TIME 9 +#define HB_VERSION_PCODE_VER 10 +#define HB_VERSION_PCODE_VER_STR 11 +#define HB_VERSION_CHANGELOG_LAST 12 +#define HB_VERSION_CHANGELOG_REV 13 +#define HB_VERSION_FLAG_PRG 14 +#define HB_VERSION_FLAG_C 15 +#define HB_VERSION_FLAG_LINKER 16 +#define HB_VERSION_BITWIDTH 17 +#define HB_VERSION_ENDIANNESS 18 /* hb_version( HB_V_ENDIANNESS ) return values. */ -#define HB_V_ENDIAN_LITTLE 1 -#define HB_V_ENDIAN_BIG 2 -#define HB_V_ENDIAN_PDP 3 +#define HB_VERSION_ENDIAN_LITTLE 1 +#define HB_VERSION_ENDIAN_BIG 2 +#define HB_VERSION_ENDIAN_PDP 3 #endif /* HB_VER_CH_ */ diff --git a/harbour/source/rtl/Makefile b/harbour/source/rtl/Makefile index 1b0c7bf871..7f8ad1e3f7 100644 --- a/harbour/source/rtl/Makefile +++ b/harbour/source/rtl/Makefile @@ -64,6 +64,7 @@ C_SOURCES=\ hbffind.c \ hbfile.c \ hbgtcore.c \ + hbi18n.c \ hbinet.c \ hbstrsh.c \ hbrandom.c \ diff --git a/harbour/source/rtl/hbi18n.c b/harbour/source/rtl/hbi18n.c new file mode 100644 index 0000000000..a9468e0c46 --- /dev/null +++ b/harbour/source/rtl/hbi18n.c @@ -0,0 +1,229 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * HB_I18N low-level Harbour functions + * + * Copyright 2008 Viktor Szakats + * www - http://www.harbour-project.org + * Loosely based on work by: + * Copyright 2003 Giancarlo Niccolai + * www - http://www.xharbour.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ + +#include "hbapi.h" +#include "hbapifs.h" +#include "hbapiitm.h" +#include "hbapierr.h" + +static const BYTE s_szHead[ 4 ] = { 193, 'H', 'B', 'L' }; + +static BOOL hb_i18n_write( HB_FHANDLE handle, char * pszComment, PHB_ITEM pTable ) +{ + ULONG i, j; + BYTE buffer[ 64 ]; + + memset( buffer, 0, sizeof( buffer ) ); + + hb_strncpy( ( char * ) buffer, pszComment, sizeof( buffer ) - 1 ); + + if( hb_fsWrite( handle, ( BYTE * ) s_szHead, sizeof( s_szHead ) ) != sizeof( s_szHead ) || + hb_fsWrite( handle, buffer, sizeof( buffer ) ) != sizeof( buffer ) ) + return FALSE; + + HB_PUT_LE_UINT32( buffer, ( UINT32 ) hb_arrayLen( pTable ) ); + + if( hb_fsWrite( handle, buffer, 4 ) != 4 ) + return FALSE; + + for( i = 1; i <= hb_arrayLen( pTable ); i++ ) + { + PHB_ITEM pRow = hb_arrayGetItemPtr( pTable, i ); + + for( j = 1; j <= 2; j++ ) + { + USHORT nStrLen = ( USHORT ) hb_arrayGetCLen( pRow, j ) + 1; /* including trailing 0 */ + + HB_PUT_LE_UINT16( buffer, ( UINT16 ) nStrLen ); + + if( hb_fsWrite( handle, ( BYTE * ) buffer, 2 ) != 2 || + hb_fsWrite( handle, ( BYTE * ) hb_arrayGetCPtr( pRow, j ), nStrLen ) != nStrLen ) + return FALSE; + } + } + + return TRUE; +} + +/* Saves a table to disk. aSortedTable must be sorted by original text. + __I18N_SAVE( cFileName | nHandle, aSortedTable [, cComment ] ) => lSuccess */ +HB_FUNC( __I18N_SAVE ) +{ + if( ISCHAR( 1 ) ) + { + HB_FHANDLE handle = hb_fsCreate( ( BYTE * ) hb_parc( 1 ), FC_NORMAL ); + + if( handle != FS_ERROR ) + { + hb_retl( hb_i18n_write( handle, hb_parcx( 3 ), hb_param( 2, HB_IT_ARRAY ) ) ); + hb_fsClose( handle ); + } + else + hb_retl( FALSE ); + } + else if( ISNUM( 1 ) ) + hb_retl( hb_i18n_write( hb_numToHandle( hb_parnint( 1 ) ), hb_parcx( 3 ), hb_param( 2, HB_IT_ARRAY ) ) ); + else + hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} + +static PHB_ITEM hb_i18n_read( HB_FHANDLE handle ) +{ + PHB_ITEM pTable = NULL; + BYTE buffer[ 64 ]; + + if( hb_fsRead( handle, buffer, sizeof( s_szHead ) ) == sizeof( s_szHead ) && + memcmp( buffer, s_szHead, sizeof( s_szHead ) ) == 0 && + hb_fsRead( handle, buffer, sizeof( buffer ) ) == sizeof( buffer ) && + hb_fsRead( handle, buffer, 4 ) == 4 ) + { + ULONG count = ( ULONG ) HB_GET_LE_UINT32( buffer ); + ULONG i, j; + + pTable = hb_itemArrayNew( count * 2 ); + + for( i = 0; i < count; i++ ) + { + for( j = 1; j <= 2; j++ ) + { + if( hb_fsRead( handle, buffer, 2 ) == 2 ) + { + USHORT nStrLen = ( USHORT ) HB_GET_LE_UINT16( buffer ); + + if( nStrLen > 0 ) + { + BYTE * string = ( BYTE * ) hb_xgrab( nStrLen ); + + if( hb_fsRead( handle, string, nStrLen ) == nStrLen && string[ nStrLen - 1 ] == '\0' ) + { + hb_arraySetCPtr( pTable, ( i << 1 ) + j, ( char * ) string, nStrLen - 1 ); + continue; + } + else + hb_xfree( string ); + } + } + + hb_itemRelease( pTable ); + pTable = NULL; + } + } + } + + return pTable; +} + +/* Loads a table in a flat array. + __I18N_LOAD( cFileName | nHandle ) => aTable. */ +HB_FUNC( __I18N_LOAD ) +{ + if( ISCHAR( 1 ) || ISNUM( 1 ) ) + { + PHB_ITEM pTable = NULL; + + if( ISCHAR( 1 ) ) + { + HB_FHANDLE handle = hb_fsOpen( ( BYTE * ) hb_parc( 1 ), FO_READ | FO_DENYNONE ); + if( handle != F_ERROR ) + { + pTable = hb_i18n_read( handle ); + hb_fsClose( handle ); + } + } + else + pTable = hb_i18n_read( hb_numToHandle( hb_parnint( 1 ) ) ); + + if( pTable ) + hb_itemReturnRelease( pTable ); + else + hb_reta( 0 ); + } + else + hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} + +/* Translate an Harbour string or return it untranslated + __I18N_GETTEXT( @cText, trs ) => NIL */ +HB_FUNC( __I18N_GETTEXT ) +{ + PHB_ITEM pFind = hb_param( 1, HB_IT_STRING ); + PHB_ITEM pTable = hb_param( 2, HB_IT_ARRAY ); + + if( pFind && pTable ) + { + char * pszFind = hb_itemGetCPtr( pFind ); + + ULONG nLow = 1; + ULONG nHigh = ( hb_arrayLen( pTable ) >> 1 ); + ULONG nMiddle; + + while( nLow <= nHigh ) + { + int result = strcmp( hb_arrayGetCPtr( pTable, ( ( nMiddle = ( nLow + nHigh ) / 2 ) << 1 ) - 1 ), pszFind ); + + if( result == 0 ) + { + hb_itemParamStore( 1, hb_arrayGetItemPtr( pTable, nMiddle << 1 ) ); + break; + } + else if( result > 0 ) + nHigh = nMiddle - 1; + else + nLow = nMiddle + 1; + } + } + else + hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} diff --git a/harbour/source/rtl/version.c b/harbour/source/rtl/version.c index 01b52303ac..0e179542ce 100644 --- a/harbour/source/rtl/version.c +++ b/harbour/source/rtl/version.c @@ -79,32 +79,32 @@ HB_FUNC( HB_VERSION ) { switch( hb_parni( 1 ) ) { - case HB_V_HARBOUR: hb_retc_buffer( hb_verHarbour() ); break; - case HB_V_COMPILER: hb_retc_buffer( hb_verCompiler() ); break; - case HB_V_VER_MAJOR: hb_retni( HB_VER_MAJOR ); break; - case HB_V_VER_MINOR: hb_retni( HB_VER_MINOR ); break; - case HB_V_VER_REV: hb_retni( HB_VER_REVISION ); break; - case HB_V_VER_STATUS: hb_retc( HB_VER_STATUS ); break; - case HB_V_VER_COUNT: hb_retni( hb_verSvnID() ); break; - case HB_V_DATE_TIME: hb_retc_buffer( hb_verBuildDate() ); break; - case HB_V_DATE: hb_retds( NULL ); break; /* TODO */ - case HB_V_TIME: hb_retc( NULL ); break; /* TODO */ - case HB_V_PCODE_VER: hb_retni( HB_PCODE_VER ); break; - case HB_V_PCODE_VER_STR: hb_retc_buffer( hb_verPCode() ); break; - case HB_V_CHANGELOG_LAST: hb_retc_const( hb_verSvnLastEntry() ); break; - case HB_V_CHANGELOG_REV: hb_retc_const( hb_verSvnChangeLogID() ); break; - case HB_V_FLAG_HARBOUR: hb_retc_const( hb_verFlagsPRG() ); break; - case HB_V_FLAG_C: hb_retc_const( hb_verFlagsC() ); break; - case HB_V_FLAG_LINKER: hb_retc_const( hb_verFlagsL() ); break; - case HB_V_BITWIDTH: hb_retni( ( int ) sizeof( void * ) ); break; + case HB_VERSION_HARBOUR: hb_retc_buffer( hb_verHarbour() ); break; + case HB_VERSION_COMPILER: hb_retc_buffer( hb_verCompiler() ); break; + case HB_VERSION_MAJOR: hb_retni( HB_VER_MAJOR ); break; + case HB_VERSION_MINOR: hb_retni( HB_VER_MINOR ); break; + case HB_VERSION_MICRO: hb_retni( HB_VER_REVISION ); break; + case HB_VERSION_STATUS: hb_retc( HB_VER_STATUS ); break; + case HB_VERSION_REVISION: hb_retni( hb_verSvnID() ); break; + case HB_VERSION_BLD_DATE_STR: hb_retc_buffer( hb_verBuildDate() ); break; + case HB_VERSION_BLD_DATE: hb_retds( NULL ); break; /* TODO */ + case HB_VERSION_BLD_TIME: hb_retc( NULL ); break; /* TODO */ + case HB_VERSION_PCODE_VER: hb_retni( HB_PCODE_VER ); break; + case HB_VERSION_PCODE_VER_STR: hb_retc_buffer( hb_verPCode() ); break; + case HB_VERSION_CHANGELOG_LAST: hb_retc_const( hb_verSvnLastEntry() ); break; + case HB_VERSION_CHANGELOG_REV: hb_retc_const( hb_verSvnChangeLogID() ); break; + case HB_VERSION_FLAG_PRG: hb_retc_const( hb_verFlagsPRG() ); break; + case HB_VERSION_FLAG_C: hb_retc_const( hb_verFlagsC() ); break; + case HB_VERSION_FLAG_LINKER: hb_retc_const( hb_verFlagsL() ); break; + case HB_VERSION_BITWIDTH: hb_retni( ( int ) sizeof( void * ) * 8 ); break; - case HB_V_ENDIANNESS: + case HB_VERSION_ENDIANNESS: #if defined( HB_LITTLE_ENDIAN ) - hb_retni( HB_V_ENDIAN_LITTLE ); + hb_retni( HB_VERSION_ENDIAN_LITTLE ); #elif defined( HB_BIG_ENDIAN ) - hb_retni( HB_V_ENDIAN_BIG ); + hb_retni( HB_VERSION_ENDIAN_BIG ); #elif defined( HB_PDP_ENDIAN ) - hb_retni( HB_V_ENDIAN_PDP ); + hb_retni( HB_VERSION_ENDIAN_PDP ); #else hb_retni( 0 ); #endif diff --git a/harbour/source/vm/runner.c b/harbour/source/vm/runner.c index b9cfa47a17..6687c5145c 100644 --- a/harbour/source/vm/runner.c +++ b/harbour/source/vm/runner.c @@ -89,7 +89,7 @@ typedef struct PHB_SYMBOLS pModuleSymbols; } HRB_BODY, * PHRB_BODY; -static const BYTE szHead[ 4 ] = { 192,'H','R','B' }; +static const BYTE s_szHead[ 4 ] = { 192, 'H', 'R', 'B' }; #define SYM_NOLINK 0 /* symbol does not have to be linked */ @@ -105,7 +105,7 @@ static int hb_hrbReadHead( char * szBody, ULONG ulBodySize, ULONG * pulBodyOffse HB_TRACE(HB_TR_DEBUG, ("hb_hrbReadHead(%p,%lu,%p)", szBody, ulBodySize, pulBodyOffset )); - if( ulBodySize < 6 || memcmp( szHead, szBody, 4 ) ) + if( ulBodySize < 6 || memcmp( s_szHead, szBody, 4 ) ) return 0; pVersion = szBody + 4; @@ -630,7 +630,7 @@ HB_FUNC( HB_HRBRUN ) char * fileOrBody = hb_parc( 1 ); PHRB_BODY pHrbBody; - if( ulLen > 4 && memcmp( szHead, fileOrBody, 4 ) == 0 ) + if( ulLen > 4 && memcmp( s_szHead, fileOrBody, 4 ) == 0 ) pHrbBody = hb_hrbLoad( fileOrBody, ulLen ); else pHrbBody = hb_hrbLoadFromFile( fileOrBody ); @@ -671,7 +671,7 @@ HB_FUNC( HB_HRBLOAD ) char * fileOrBody = hb_parc( 1 ); PHRB_BODY pHrbBody; - if( ulLen > 4 && memcmp( szHead, fileOrBody, 4 ) == 0 ) + if( ulLen > 4 && memcmp( s_szHead, fileOrBody, 4 ) == 0 ) pHrbBody = hb_hrbLoad( fileOrBody, ulLen ); else pHrbBody = hb_hrbLoadFromFile( fileOrBody ); diff --git a/harbour/utils/hbtest/rt_str.prg b/harbour/utils/hbtest/rt_str.prg index 1e664df1f4..c2fac3a5a8 100644 --- a/harbour/utils/hbtest/rt_str.prg +++ b/harbour/utils/hbtest/rt_str.prg @@ -534,7 +534,7 @@ PROCEDURE Main_STR() /* REPLICATE() */ #ifdef __HARBOUR__ - IF hb_version( HB_V_BITWIDTH ) >= 64 + IF hb_version( HB_VERSION_BITWIDTH ) >= 64 TEST_LINE( Replicate("XXX", 9000000000000000000) , "E BASE 1234 String overflow REPLICATE A:2:C:XXX;N:9000000000000000000 F:S" ) ELSE TEST_LINE( Replicate("XXX", 2000000000) , "E BASE 1234 String overflow REPLICATE A:2:C:XXX;N:2000000000 F:S" )