diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 9e188bca6f..3bdce64732 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,28 @@ +19991006-01:10 EDT David G. Holm + + * source/rtl/dates.c + % SECONDS() now uses ftime() and localtime() for all platforms. + + * source/rtl/environ.c + + Added HB_VERSION() changes supplied by Jose Lalin with + corrections for the compiler version and revision for + Borland C 3.1 and 5.x, Cygnus GCC with Cygwin, + Cygnus GCC with Mingw32, and Delorie GCC. + + * source/rtl/set.c + + Added HB_DEFPATH() and HB___DEFPATH() supplied by Jose Lalin. + + * include/extend.h + * source/rtl/fm.c + % Only use hb_xmemcopy() and hb_xmemset() when the size of an + unsigned int is not the same as the size of an unsigned long. + + * include/gtapi.h + * source/rtl/console.c + * source/rtl/gtapi.c + ! DEVPOS(), SETPOS(), console cursor position, and console display + functions modified for improved Clipper compatibility. + 19991005-23:20 EDT Paul Tucker + include/harbour.ch * This file is meant as a repository of defines or translations needed diff --git a/harbour/include/extend.h b/harbour/include/extend.h index 31b4b9203f..6860cd2976 100644 --- a/harbour/include/extend.h +++ b/harbour/include/extend.h @@ -282,13 +282,16 @@ extern void * hb_xgrab( ULONG ulSize ); /* allocates memory, e extern void hb_xfree( void * pMem ); /* frees memory */ extern void * hb_xrealloc( void * pMem, ULONG ulSize ); /* reallocates memory */ extern ULONG hb_xsize( void * pMem ); /* returns the size of an allocated memory block */ + +#if UINT_MAX == ULONG_MAX + /* NOTE: memcpy/memset can work with ULONG data blocks */ + #define hb_xmemcpy memcpy + #define hb_xmemset memset +#else + /* NOTE: otherwise, the hb_xmemcpy and hb_xmemset functions + will be used to copy and/or set ULONG data blocks */ extern void * hb_xmemcpy( void * pDestArg, void * pSourceArg, ULONG ulLen ); /* copy more than memcpy() can */ extern void * hb_xmemset( void * pDestArg, int iFill, ULONG ulLen ); /* set more than memset() can */ - -#if defined( __WATCOMC__ ) && defined( __386__ ) -/* NOTE: memcpy/memset can work with data block larger then 64kB */ -#define hb_xmemcpy memcpy -#define hb_xmemset memset #endif /* array management */ diff --git a/harbour/include/gtapi.h b/harbour/include/gtapi.h index 1a23e35926..c1e0e9e9cb 100644 --- a/harbour/include/gtapi.h +++ b/harbour/include/gtapi.h @@ -58,7 +58,7 @@ extern USHORT hb_gtDispEnd( void ); extern USHORT hb_gtGetBlink( BOOL * pbBlink ); extern USHORT hb_gtGetColorStr( char * pszColorString ); extern USHORT hb_gtGetCursor( USHORT * puiCursorShape ); -extern USHORT hb_gtGetPos( USHORT * puiRow, USHORT * puiCol ); +extern USHORT hb_gtGetPos( short * puiRow, short * puiCol ); extern BOOL hb_gtIsColor( void ); extern USHORT hb_gtMaxCol( void ); extern USHORT hb_gtMaxRow( void ); @@ -74,7 +74,7 @@ extern USHORT hb_gtSetBlink( BOOL bBlink ); extern USHORT hb_gtSetColorStr( char * pszColorString ); extern USHORT hb_gtSetCursor( USHORT uiCursorShape ); extern USHORT hb_gtSetMode( USHORT uiRows, USHORT uiCols ); -extern USHORT hb_gtSetPos( USHORT uiRow, USHORT uiCol ); +extern USHORT hb_gtSetPos( short uiRow, short uiCol ); extern USHORT hb_gtSetSnowFlag( BOOL bNoSnow ); extern USHORT hb_gtWrite( BYTE * pbyStr, ULONG ulLen ); extern USHORT hb_gtWriteAt( USHORT uiRow, USHORT uiCol, BYTE * pbyStr, ULONG ulLen ); diff --git a/harbour/source/rtl/console.c b/harbour/source/rtl/console.c index d3cf94d2df..e6a9515463 100644 --- a/harbour/source/rtl/console.c +++ b/harbour/source/rtl/console.c @@ -98,8 +98,8 @@ #endif static BOOL s_bInit = FALSE; -static USHORT s_uiDevRow; -static USHORT s_uiDevCol; +static short s_iDevRow; +static short s_iDevCol; static USHORT s_uiPRow; static USHORT s_uiPCol; static char s_szCrLf[ CRLF_BUFFER_LEN ]; @@ -143,11 +143,11 @@ void hb_consoleInitialize( void ) #ifdef HARBOUR_USE_GTAPI hb_gtInit(); - hb_gtGetPos( &s_uiDevRow, &s_uiDevCol ); + hb_gtGetPos( &s_iDevRow, &s_iDevCol ); hb_gtSetCursor( SC_NORMAL ); #else - s_uiDevRow = 0; - s_uiDevCol = 0; + s_iDevRow = 0; + s_iDevCol = 0; #endif s_bInit = TRUE; @@ -355,14 +355,14 @@ void hb_outstd( char * pStr, ULONG ulLen ) if( isatty( s_iFilenoStdout ) ) #endif { - s_uiDevRow = hb_gt_Row(); - s_uiDevCol = hb_gt_Col(); - hb_gtSetPos( s_uiDevRow, s_uiDevCol ); + s_iDevRow = hb_gt_Row(); + s_iDevCol = hb_gt_Col(); + hb_gtSetPos( s_iDevRow, s_iDevCol ); } hb_gtPostExt(); } #else - adjust_pos( pStr, ulLen, &s_uiDevRow, &s_uiDevCol, hb_max_row(), hb_max_col() ); + adjust_pos( pStr, ulLen, &s_iDevRow, &s_iDevCol, hb_max_row(), hb_max_col() ); #endif } @@ -390,14 +390,14 @@ void hb_outerr( char * pStr, ULONG ulLen ) if( isatty( s_iFilenoStdout ) ) #endif { - s_uiDevRow = hb_gt_Row(); - s_uiDevCol = hb_gt_Col(); - hb_gtSetPos( s_uiDevRow, s_uiDevCol ); + s_iDevRow = hb_gt_Row(); + s_iDevCol = hb_gt_Col(); + hb_gtSetPos( s_iDevRow, s_iDevCol ); } hb_gtPostExt(); } #else - adjust_pos( pStr, ulLen, &s_uiDevRow, &s_uiDevCol, hb_max_row(), hb_max_col() ); + adjust_pos( pStr, ulLen, &s_iDevRow, &s_iDevCol, hb_max_row(), hb_max_col() ); #endif } @@ -408,12 +408,12 @@ static void hb_altout( char * pStr, ULONG ulLen ) { #ifdef HARBOUR_USE_GTAPI hb_gtWriteCon( ( BYTE * ) pStr, ulLen ); - hb_gtGetPos( &s_uiDevRow, &s_uiDevCol ); + hb_gtGetPos( &s_iDevRow, &s_iDevCol ); #else USHORT user_ferror = hb_fsError(); /* Save current user file error code */ hb_fsWriteLarge( s_iFilenoStdout, ( BYTE * ) pStr, ulLen ); hb_fsSetError( user_ferror ); /* Restore last user file error code */ - adjust_pos( pStr, ulLen, &s_uiDevRow, &s_uiDevCol, hb_max_row(), hb_max_col() ); + adjust_pos( pStr, ulLen, &s_iDevRow, &s_iDevCol, hb_max_row(), hb_max_col() ); #endif } @@ -439,8 +439,7 @@ static void hb_altout( char * pStr, ULONG ulLen ) USHORT user_ferror = hb_fsError(); /* Save current user file error code */ hb_fsWriteLarge( hb_set.hb_set_printhan, ( BYTE * ) pStr, ulLen ); hb_fsSetError( user_ferror ); /* Restore last user file error code */ - if( ulLen + s_uiPCol > USHRT_MAX ) s_uiPCol = USHRT_MAX; - else s_uiPCol += ulLen; + s_uiPCol += ulLen; } } @@ -453,20 +452,19 @@ static void hb_devout( char * pStr, ULONG ulLen ) USHORT user_ferror = hb_fsError(); /* Save current user file error code */ hb_fsWriteLarge( hb_set.hb_set_printhan, ( BYTE * ) pStr, ulLen ); hb_fsSetError( user_ferror ); /* Restore last user file error code */ - if( ulLen + s_uiPCol > USHRT_MAX ) s_uiPCol = USHRT_MAX; - else s_uiPCol += ulLen; + s_uiPCol += ulLen; } else { #ifdef HARBOUR_USE_GTAPI /* Otherwise, display to console */ - hb_gtWrite( ( BYTE * ) pStr, ulLen ); - hb_gtGetPos( &s_uiDevRow, &s_uiDevCol ); + hb_gtWriteAt( s_iDevRow, s_iDevCol, ( BYTE * ) pStr, ulLen ); + hb_gtGetPos( &s_iDevRow, &s_iDevCol ); #else USHORT user_ferror = hb_fsError(); /* Save current user file error code */ hb_fsWriteLarge( s_iFilenoStdout, ( BYTE * ) pStr, ulLen ); hb_fsSetError( user_ferror ); /* Restore last user file error code */ - adjust_pos( pStr, ulLen, &s_uiDevRow, &s_uiDevCol, hb_max_row(), hb_max_col() ); + adjust_pos( pStr, ulLen, &s_iDevRow, &s_iDevCol, hb_max_row(), hb_max_col() ); #endif } } @@ -476,66 +474,66 @@ static void hb_dispout( char * pStr, ULONG ulLen ) { #ifdef HARBOUR_USE_GTAPI /* Display to console */ - hb_gtWrite( ( BYTE * ) pStr, ulLen ); - hb_gtGetPos( &s_uiDevRow, &s_uiDevCol ); + hb_gtWriteAt( s_iDevRow, s_iDevCol, ( BYTE * ) pStr, ulLen ); + hb_gtGetPos( &s_iDevRow, &s_iDevCol ); #else USHORT user_ferror = hb_fsError(); /* Save current user file error code */ hb_fsWriteLarge( s_iFilenoStdout, ( BYTE * ) pStr, ulLen ); hb_fsSetError( user_ferror ); /* Restore last user file error code */ - adjust_pos( pStr, ulLen, &s_uiDevRow, &s_uiDevCol, hb_max_row(), hb_max_col() ); + adjust_pos( pStr, ulLen, &s_iDevRow, &s_iDevCol, hb_max_row(), hb_max_col() ); #endif } -void hb_setpos( USHORT row, USHORT col ) +void hb_setpos( short row, short col ) { #ifdef HARBOUR_USE_GTAPI hb_gtSetPos( row, col ); #else - USHORT uiCount; + short iCount; - if( row < s_uiDevRow || col < s_uiDevCol ) + if( row < s_iDevRow || col < s_iDevCol ) { fputs( s_szCrLf, stdout ); - s_uiDevCol = 0; - s_uiDevRow++; + s_iDevCol = 0; + s_iDevRow++; } - else if( row > s_uiDevRow ) s_uiDevCol = 0; - for( uiCount = s_uiDevRow; uiCount < row; uiCount++ ) + else if( row > s_iDevRow ) s_iDevCol = 0; + for( iCount = s_iDevRow; iCount < row; iCount++ ) fputs( s_szCrLf, stdout ); - for( uiCount = s_uiDevCol; uiCount < col; uiCount++ ) + for( iCount = s_iDevCol; iCount < col; iCount++ ) fputc( ' ', stdout ); fflush( stdout ); #endif - s_uiDevRow = row; - s_uiDevCol = col; + s_iDevRow = row; + s_iDevCol = col; } -void hb_devpos( USHORT row, USHORT col ) +void hb_devpos( short row, short col ) { - USHORT uiCount; /* Position printer if SET DEVICE TO PRINTER and valid printer file otherwise position console */ if( hb_set.hb_set_printhan != FS_ERROR && hb_stricmp( hb_set.HB_SET_DEVICE, "PRINTER" ) == 0 ) { + USHORT uiCount, uiProw = ( USHORT ) row, uiPcol = ( USHORT ) col; USHORT user_ferror = hb_fsError(); /* Save current user file error code */ - if( row < s_uiPRow ) + if( uiProw < s_uiPRow ) { - hb_fsWrite( hb_set.hb_set_printhan, ( BYTE * ) "\x0C", 1 ); + hb_fsWrite( hb_set.hb_set_printhan, ( BYTE * ) "\x0C\x0D", 2 ); s_uiPRow = s_uiPCol = 0; } - for( uiCount = s_uiPRow; uiCount < row; uiCount++ ) + for( uiCount = s_uiPRow; uiCount < uiProw; uiCount++ ) hb_fsWrite( hb_set.hb_set_printhan, ( BYTE * ) s_szCrLf, CRLF_BUFFER_LEN-1 ); - if( row > s_uiPRow ) s_uiPCol = 0; - col += hb_set.HB_SET_MARGIN; + if( uiProw > s_uiPRow ) s_uiPCol = 0; + uiPcol += hb_set.HB_SET_MARGIN; - for( uiCount = s_uiPCol; uiCount < col; uiCount++ ) + for( uiCount = s_uiPCol; uiCount < uiPcol; uiCount++ ) hb_fsWrite( hb_set.hb_set_printhan, ( BYTE * ) " ", 1 ); - s_uiPRow = row; - s_uiPCol = col; + s_uiPRow = uiProw; + s_uiPCol = uiPcol; hb_fsSetError( user_ferror ); /* Restore last user file error code */ } else @@ -604,21 +602,8 @@ HARBOUR HB_SETPOS( void ) /* Sets the screen position */ { if( ISNUM( 1 ) && ISNUM( 2 ) ) { - int i_row = hb_parni( 1 ); - int i_col = hb_parni( 2 ); - USHORT row, col; - - /* Limit the new position to the range (0,0) to (MAXROW(),MAXCOL()) */ - if( i_row < 0 ) row = 0; - else if( i_row > hb_max_row() ) row = hb_max_row(); - else row = i_row; - - if( i_col < 0 ) col = 0; - else if( i_col > hb_max_col() ) col = hb_max_col(); - else col = i_col; - /* Set the new screen position */ - hb_setpos( row, col ); + hb_setpos( hb_parni( 1 ), hb_parni( 2 ) ); } } else @@ -631,12 +616,11 @@ HARBOUR HB_SETPOSBS( void ) if( hb_pcount() == 0 ) { #ifdef HARBOUR_USE_GTAPI - USHORT uiRow; - USHORT uiCol; + short iRow, iCol; /* NOTE: Clipper does no checks about reaching the border or anything */ - hb_gtGetPos( &uiRow, &uiCol ); - hb_gtSetPos( uiRow, uiCol + 1 ); + hb_gtGetPos( &iRow, &iCol ); + hb_gtSetPos( iRow, iCol + 1 ); #endif } else @@ -649,21 +633,8 @@ HARBOUR HB_DEVPOS( void ) /* Sets the screen and/or printer position */ { if( ISNUM( 1 ) && ISNUM( 2 ) ) { - long l_row = hb_parnl( 1 ); - long l_col = hb_parnl( 2 ); - USHORT row, col; - - /* Limit the new position to the range (0,0) to (65535,65535) */ - if( l_row < 0 ) row = 0; - else if( l_row > USHRT_MAX ) row = USHRT_MAX; - else row = l_row; - - if( l_col < 0 ) col = 0; - else if( l_col > USHRT_MAX ) col = USHRT_MAX; - else col = l_col; - /* Set the new screen position */ - hb_devpos( row, col ); + hb_devpos( hb_parni( 1 ), hb_parni( 2 ) ); } } else @@ -778,18 +749,8 @@ HARBOUR HB_SETPRC( void ) /* Sets the current printer row and column positions * { if( ISNUM( 1 ) && ISNUM( 2 ) ) { - long l_row = hb_parnl( 1 ); - long l_col = hb_parnl( 2 ); - - /* Limit the new position to the range (0,0) to (65535,65535) */ - - if( l_row < 0 ) s_uiPRow = 0; - else if( l_row > USHRT_MAX ) s_uiPRow = USHRT_MAX; - else s_uiPRow = l_row; - - if( l_col < 0 ) s_uiPCol = 0; - else if( l_col > USHRT_MAX ) s_uiPCol = USHRT_MAX; - else s_uiPCol = l_col; + s_uiPRow = ( USHORT ) hb_parni( 1 ); + s_uiPCol = ( USHORT ) hb_parni( 2 ); } } @@ -829,11 +790,11 @@ HARBOUR HB_SCROLL( void ) /* Scrolls a screen region (requires the GT API) */ && v_scroll == 0 && h_scroll == 0 ) { USHORT uiCount; - s_uiDevRow = iMR; - for( uiCount = 0; uiCount < s_uiDevRow ; uiCount++ ) + s_iDevRow = iMR; + for( uiCount = 0; uiCount < s_iDevRow ; uiCount++ ) fputs( s_szCrLf, stdout ); fflush( stdout ); - s_uiDevRow = s_uiDevCol = 0; + s_iDevRow = s_iDevCol = 0; } #endif } @@ -853,9 +814,9 @@ HARBOUR HB_ROW( void ) /* Return the current screen row position (zero origin) * if( hb_pcount() == 0 ) { #ifdef HARBOUR_USE_GTAPI - hb_gtGetPos( &s_uiDevRow, &s_uiDevCol ); + hb_gtGetPos( &s_iDevRow, &s_iDevCol ); #endif - hb_retni( s_uiDevRow ); + hb_retni( s_iDevRow ); } else hb_errRT_BASE( EG_ARGCOUNT, 3000, NULL, "ROW" ); /* NOTE: Clipper catches this at compile time! */ @@ -866,9 +827,9 @@ HARBOUR HB_COL( void ) /* Return the current screen column position (zero origin if( hb_pcount() == 0 ) { #ifdef HARBOUR_USE_GTAPI - hb_gtGetPos( &s_uiDevRow, &s_uiDevCol ); + hb_gtGetPos( &s_iDevRow, &s_iDevCol ); #endif - hb_retni( s_uiDevCol ); + hb_retni( s_iDevCol ); } else hb_errRT_BASE( EG_ARGCOUNT, 3000, NULL, "COL" ); /* NOTE: Clipper catches this at compile time! */ diff --git a/harbour/source/rtl/dates.c b/harbour/source/rtl/dates.c index e17bd1bf2c..d13498a903 100644 --- a/harbour/source/rtl/dates.c +++ b/harbour/source/rtl/dates.c @@ -73,13 +73,9 @@ #include #include +#include #if defined(__TURBOC__) || defined(__BORLANDC__) || defined(__DJGPP__) #include -#elif defined(_MSC_VER) || defined(__MINGW32__) - #include - #if defined(__MINGW32__) - #define _timeb timeb - #endif #endif #ifndef HARBOUR_STRICT_CLIPPER_COMPATIBILITY #define HB_OPTIMIZE_DTOS @@ -87,27 +83,19 @@ double hb_secondsToday( void ) { -#if defined(__TURBOC__) || defined(__BORLANDC__) || defined(__DJGPP__) - struct time t; - gettime( &t ); - return ( ( t.ti_hour * 3600 ) + ( t.ti_min * 60 ) + t.ti_sec ) + ( double ) t.ti_hund / 100; -#elif defined(_MSC_VER) || defined(__MINGW32__) - struct _timeb tb; +#if defined(_MSC_VER) + #define timeb _timeb + #define ftime _ftime +#endif + struct timeb tb; struct tm *oTime; - _ftime( &tb ); + ftime( &tb ); oTime = localtime( &tb.time ); return ( oTime->tm_hour * 3600 ) + ( oTime->tm_min * 60 ) + oTime->tm_sec + ( ( double ) tb.millitm / 1000 ); -#else - time_t t; - struct tm *oTime; - time( &t ); - oTime = localtime( &t ); - return ( oTime->tm_hour * 3600 ) + ( oTime->tm_min * 60 ) + oTime->tm_sec; -#endif } char * hb_cmonth( int iMonth ) diff --git a/harbour/source/rtl/environ.c b/harbour/source/rtl/environ.c index 887255e084..c892cc1051 100644 --- a/harbour/source/rtl/environ.c +++ b/harbour/source/rtl/environ.c @@ -285,6 +285,7 @@ HARBOUR HB_OS( void ) #define HB_VERSION_BUFFER_LEN 80 + char * hb_version( USHORT uiMode ) { char * pszVersion = ( char * ) hb_xgrab( HB_VERSION_BUFFER_LEN ); @@ -297,38 +298,103 @@ char * hb_version( USHORT uiMode ) /* Optionally include the Compiler name and version, if available. */ char * compiler = ( char * ) NULL; int version = 0; + int revision = 0; + + #if defined(__IBMC__) || defined(__IBMCPP__) + + #if defined(__IBMC__) + version = __IBMC__; + #else + version = __IBMCPP__; + #endif + + if( version >= 300 ) + compiler = "IBM Visual Age C++"; + else + compiler = "IBM C++"; + + version /= 100; + revision = version % 100; - #if defined(__IBMCPP__) - compiler = "IBM C++"; - version = __IBMCPP__; #elif defined(__BORLANDC__) - compiler = "Borland C"; - version = __BORLANDC__; + + compiler = "Borland C++"; + if( __BORLANDC__ == 1040 ) + { + /* Version 3.1 */ + version = 3; + revision = 1; + } + else if( __BORLANDC__ >= 1280 ) + { + /* Version 5.x */ + version = __BORLANDC__ >> 8; + revision = ( __BORLANDC__ & 0xff ) >> 4; + } + else + { + /* Version 4.x */ + version = __BORLANDC__ >> 8; + revision = ( __BORLANDC__ - 1 & 0xff) >> 4; + } + #elif defined(__TURBOC__) - compiler = "Turbo C"; - version = __TURBOC__; + + compiler = "Borland Turbo C"; + version = __TURBOC__ >> 8; + revision = __TURBOC__ & 0xff; + #elif defined(_MSC_VER) - compiler = "Microsoft C"; - version = _MSC_VER; + + compiler = "Microsoft C/C++"; + version = _MSC_VER / 100; + revision = _MSC_VER % 100; + #elif defined(__MPW__) + compiler = "MPW C"; - version = __MPW__; - #elif defined(__WATCOMC_) - compiler = "Watcom C"; - version = __WATCOMC__; + version = __MPW__ / 100; + revision = __MPW__ % 100; + + #elif defined(__WATCOMC__) + + compiler = "Watcom C/C++"; + version = __WATCOMC__ / 100; + revision = __WATCOMC__ % 100; + #elif defined(__DJGPP__) + compiler = "Delorie GCC"; - version = __DJGPP__; - #elif defined(__CYGWIN__) - compiler = "Cygnus GCC (cygwin)"; - version = __CYGWIN__; - #elif defined(__MINGW32__) - compiler = "Cygnus GCC (mingw32)"; - version = __MINGW32__; - #elif defined(__GNUC__) - compiler = "GNU C"; version = __GNUC__; + revision = __GNUC_MINOR__; + + #elif defined(__CYGWIN__) + + compiler = "Cygnus GCC (Cygwin)"; + version = __GNUC__; + revision = __GNUC_MINOR__; + + + #elif defined(__MINGW32__) + + compiler = hb_xgrab( 80 ); + sprintf( compiler, "Cygnus GCC (Mingw32 %g)", __MINGW32__ ); + version = __GNUC__; + revision = __GNUC_MINOR__; + + #elif defined(__GNUC__) + + #ifdef __EMX__ + compiler = "GNU C/EMX C"; + #else + compiler = "GNU C"; + #endif + + version = __GNUC__; + revision = __GNUC_MINOR__; + #endif + if( compiler ) { strncat( pszVersion, " (", HB_VERSION_BUFFER_LEN ); @@ -336,13 +402,16 @@ char * hb_version( USHORT uiMode ) if( version ) { char buf[ 40 ]; - sprintf( buf, "(%d)", version ); + sprintf( buf, "(%d.%d)", version, revision ); strncat( pszVersion, " ", HB_VERSION_BUFFER_LEN ); strncat( pszVersion, buf, HB_VERSION_BUFFER_LEN ); } strncat( pszVersion, ")", HB_VERSION_BUFFER_LEN ); pszVersion[ HB_VERSION_BUFFER_LEN - 1 ] = '\0'; } + #if defined(__MINGW32__) + hb_xfree( compiler ); + #endif } return pszVersion; diff --git a/harbour/source/rtl/fm.c b/harbour/source/rtl/fm.c index ae9ed22f08..dfac3dcdc8 100644 --- a/harbour/source/rtl/fm.c +++ b/harbour/source/rtl/fm.c @@ -178,6 +178,11 @@ void hb_xexit( void ) /* Deinitialize fixed memory subsystem */ #endif } +#if UINT_MAX != ULONG_MAX + +/* hb_xmemcpy and hb_xmemset are only needed when + unsigned int and unsigned long differ in length */ + void * hb_xmemcpy( void * pDestArg, void * pSourceArg, ULONG ulLen ) { BYTE * pDest = ( BYTE * ) pDestArg; @@ -230,6 +235,8 @@ void * hb_xmemset( void * pDestArg, int iFill, ULONG ulLen ) return pDestArg; } +#endif + HARBOUR HB_MEMORY( void ) { /* TODO: Implement */ diff --git a/harbour/source/rtl/gtapi.c b/harbour/source/rtl/gtapi.c index 0d33af65c7..fa1bf40b0d 100644 --- a/harbour/source/rtl/gtapi.c +++ b/harbour/source/rtl/gtapi.c @@ -37,6 +37,9 @@ * GTAPI.C: Generic Terminal for Harbour * * Latest mods: + * 1.81 19991005 dholm Made the hb_gtWrite(), hb_gtWriteAt(), and + * hb_gtWriteCon() functions and the cursor + * positioning more compatible with Clipper. * 1.66 19990830 vszel Reformatted using Harbour standard. Some * small cleanups. * 1.65 19990830 ptucker Handle nesting of gtPre/PostExt - corrected @@ -99,12 +102,13 @@ #include "set.h" #include "gtapi.h" -static USHORT s_uiCurrentRow = 0; -static USHORT s_uiCurrentCol = 0; +static short s_iCurrentRow = 0; +static short s_iCurrentCol = 0; static USHORT s_uiDispCount = 0; static USHORT s_uiPreCount = 0; static USHORT s_uiPreCNest = 0; static USHORT s_uiColorIndex = 0; +static USHORT s_uiCursorShape = 0; static int * s_Color; /* masks: 0x0007 Foreground 0x0070 Background @@ -568,7 +572,7 @@ USHORT hb_gtSetColorStr( char * fpColorString ) USHORT hb_gtGetCursor( USHORT * uipCursorShape ) { - int i = hb_gt_GetCursorStyle(); + int i = s_uiCursorShape = hb_gt_GetCursorStyle(); int rc = 0; if( i <= SC_SPECIAL2 ) @@ -586,29 +590,51 @@ USHORT hb_gtGetCursor( USHORT * uipCursorShape ) USHORT hb_gtSetCursor( USHORT uiCursorShape ) { hb_gt_SetCursorStyle( uiCursorShape ); + s_uiCursorShape = uiCursorShape; return 0; } -USHORT hb_gtGetPos( USHORT * uipRow, USHORT * uipCol ) +USHORT hb_gtGetPos( short * ipRow, short * ipCol ) { - *uipRow = s_uiCurrentRow = hb_gt_Row(); - *uipCol = s_uiCurrentCol = hb_gt_Col(); + if( s_iCurrentRow >= 0 && s_iCurrentRow <= hb_gtMaxRow() + && s_iCurrentCol >= 0 && s_iCurrentCol <= hb_gtMaxCol() ) + { + /* Only return the actual cursor position if the current + cursor position was not previously set out of bounds. */ + s_iCurrentRow = hb_gt_Row(); + s_iCurrentCol = hb_gt_Col(); + } + *ipRow = s_iCurrentRow; + *ipCol = s_iCurrentCol; return 0; } -USHORT hb_gtSetPos( USHORT uiRow, USHORT uiCol ) +USHORT hb_gtSetPos( short iRow, short iCol ) { - /* TODO: in this situation Clipper just turns off the cursor */ - /* any further writes would be accounted for by clipping */ - if( uiRow > hb_gtMaxRow() || uiCol > hb_gtMaxCol() ) - return 1; + BOOL set_cursor = TRUE; - s_uiCurrentRow = uiRow; - s_uiCurrentCol = uiCol; + /* Validate the new cursor position */ + if( iRow < 0 || iCol < 0 || iRow > hb_gtMaxRow() || iCol > hb_gtMaxCol() ) + { + /* Disable cursor if out of bounds */ + hb_gt_SetCursorStyle( SC_NONE ); + set_cursor = FALSE; + } - hb_gt_SetPos( uiRow, uiCol ); + if( set_cursor ) hb_gt_SetPos( iRow, iCol ); + + /* Check the old cursor position */ + if( s_iCurrentRow < 0 || s_iCurrentCol < 0 || s_iCurrentRow > hb_gtMaxRow() + || s_iCurrentCol > hb_gtMaxCol() ) + { + /* If back in bounds, enable the cursor */ + if( set_cursor) hb_gt_SetCursorStyle( s_uiCursorShape ); + } + + s_iCurrentRow = iRow; + s_iCurrentCol = iCol; return 0; } @@ -708,80 +734,31 @@ USHORT hb_gtSetSnowFlag( BOOL bNoSnow ) USHORT hb_gtWrite( BYTE * fpStr, ULONG length ) { - int iRow, iCol, iMaxCol, iMaxRow; + short iMaxCol, iMaxRow; ULONG size = length; BYTE attr = s_Color[ s_uiColorIndex ] & 0xFF; - BYTE * fpPointer = fpStr; - /* TODO: this is doing more work than needed */ - - /* Determine where the cursor is going to end up */ - iRow = s_uiCurrentRow; - iCol = s_uiCurrentCol; + /* Optimize access to max row and col positions */ iMaxRow = hb_gtMaxRow(); iMaxCol = hb_gtMaxCol(); - length = ( length < iMaxCol - iCol + 1 ) ? length : iMaxCol - iCol + 1; - - size = length; - - if( iCol + size > iMaxCol ) + /* Display the text if the cursor is on screen */ + if( s_iCurrentCol >= 0 && s_iCurrentCol <= iMaxCol + && s_iCurrentRow >= 0 && s_iCurrentRow <= iMaxRow ) { - /* Calculate eventual row position and the remainder size for the column adjust */ - iRow += ( size / ( iMaxCol + 1 ) ); - size = size % ( iMaxCol + 1 ); + /* Truncate the text if the cursor will end up off the right edge */ + if( s_iCurrentCol + size > iMaxCol + 1 ) size = iMaxCol - s_iCurrentCol; + hb_gt_Puts( s_iCurrentRow, s_iCurrentCol, attr, fpStr, size ); } - iCol += size; - if( iCol > iMaxCol ) - { - /* Column movement overflows onto next row */ - iRow++; - iCol -= ( iMaxCol + 1 ); - } - /* If needed, prescroll the display to the new position and adjust the current row - position to account for the prescroll */ - if( iRow > iMaxRow ) - { - int iTemp; - - hb_gtScroll( 0, 0, iMaxRow, iMaxCol, iRow - iMaxRow, 0 ); - iTemp = s_uiCurrentRow - ( iRow - iMaxRow ); - if( iTemp < 0 ) - { - /* The string is too long to fit on the screen. Only display part of it. */ - fpPointer += iMaxCol * abs( iTemp ); - iTemp = 0; - if( s_uiCurrentCol > 0 ) - { - /* Ensure that the truncated text will fill the screen */ - fpPointer -= s_uiCurrentCol; - s_uiCurrentCol = 0; - } - } - else size = length; - - /* Save the new starting row and the new ending row */ - s_uiCurrentRow = iTemp; - iRow = iMaxRow; - } - else size = length; - - /* Now the text string can be displayed */ - hb_gt_Puts( s_uiCurrentRow, s_uiCurrentCol, attr, fpPointer, size ); - - /* Finally, save the new cursor position */ - hb_gtSetPos( iRow, iCol ); + /* Finally, save the new cursor position, even if off-screen */ + hb_gtSetPos( s_iCurrentRow, s_iCurrentCol + length ); return 0; } USHORT hb_gtWriteAt( USHORT uiRow, USHORT uiCol, BYTE * fpStr, ULONG length ) { - int rc; - - if( ( rc = hb_gtSetPos( uiRow, uiCol ) ) != 0 ) - return rc; - + hb_gtSetPos( uiRow, uiCol ); return hb_gtWrite( fpStr, length ); } @@ -789,14 +766,22 @@ USHORT hb_gtWriteCon( BYTE * fpStr, ULONG length ) { int rc = 0, nLen = 0; BOOL ldisp = FALSE; - USHORT uiRow = s_uiCurrentRow, uiCol = s_uiCurrentCol; - USHORT uiMaxRow = hb_gtMaxRow(); - USHORT uiMaxCol = hb_gtMaxCol(); + BOOL lnewline = FALSE; + short iRow = s_iCurrentRow, iCol = s_iCurrentCol; + short iMaxRow = hb_gtMaxRow(); + short iMaxCol = hb_gtMaxCol(); BYTE ch; BYTE * fpPtr = fpStr; #define STRNG_SIZE 500 BYTE strng[ STRNG_SIZE ]; + /* Limit the starting cursor position to maxrow(),maxcol() + on the high end, but don't limit it on the low end. */ + if( iRow > iMaxRow ) iRow = iMaxRow; + if( iCol > iMaxCol ) iCol = iMaxCol; + if( iRow != s_iCurrentRow || iCol != s_iCurrentCol) + hb_gtSetPos( iRow, iCol ); + while( length-- ) { ch = *fpPtr++; @@ -806,75 +791,73 @@ USHORT hb_gtWriteCon( BYTE * fpStr, ULONG length ) break; case HB_CHAR_BS: -/* - COMMENT: Clipper does not scroll backwards up the screen! - if( uiCol > 0 ) uiCol--; - else if( uiRow > 0 ) + if( iCol > 0 ) { - uiRow--; - uiCol = uiMaxCol; - } - else - { - hb_gtScroll( 0, 0, uiMaxRow, uiMaxCol, -1, 0 ); - uiCol = uiMaxCol; - } -*/ - - if( uiCol > 0 ) - { - --uiCol; + --iCol; ldisp = TRUE; } - else if( uiCol == 0 && uiRow > 0 ) + else if( iCol == 0 && iRow > 0 ) { - uiCol = uiMaxCol; - --uiRow; + iCol = iMaxCol; + --iRow; ldisp = TRUE; } break; case HB_CHAR_LF: -/* - if( uiRow < uiMaxRow ) uiRow++; - else - hb_gtScroll( 0, 0, uiMaxRow, uiMaxCol, 1, 0 ); - - hb_gtSetPos( uiRow, uiCol ); -*/ - ++uiRow; + if( iRow >= 0 ) ++iRow; ldisp = TRUE; + lnewline = TRUE; break; case HB_CHAR_CR: - uiCol = 0; + iCol = 0; if( *fpPtr != HB_CHAR_LF ) ldisp = TRUE; break; default: - if( ++uiCol > uiMaxCol ) + iCol++; + if( iCol > iMaxCol || iCol <= 0 ) { - uiCol = 0; - ++uiRow; + /* If the cursor position started off the left edge, + don't display the first character of the string */ + if( iCol > 0 ) strng[ nLen++ ] = ch; + /* Always advance to the first column of the next row + when the right edge is reached or when the cursor + started off the left edge, unless the cursor is off + the top edge, in which case only change the column */ + iCol = 0; + if( iRow >= 0 ) ++iRow; ldisp = TRUE; + lnewline = TRUE; } - strng[ nLen++ ] = ch; + else strng[ nLen++ ] = ch; + + /* Special handling for a really wide screen or device */ if( nLen >= STRNG_SIZE ) ldisp = TRUE; } if( ldisp || ! length ) { - if( nLen ) + if( nLen && s_iCurrentRow >= 0 ) rc = hb_gtWrite( strng, nLen ); nLen = 0; - if( uiRow > uiMaxRow ) + if( iRow > iMaxRow ) { - hb_gtScroll( 0, 0, uiMaxRow, uiMaxCol, uiRow - uiMaxRow, 0 ); - uiRow = uiMaxRow; - uiCol = 0; + /* Normal scroll */ + hb_gtScroll( 0, 0, iMaxRow, iMaxCol, iRow - iMaxRow, 0 ); + iRow = iMaxRow; + iCol = 0; } - hb_gtSetPos( uiRow, uiCol ); + else if( iRow < 0 && lnewline ) + { + /* Special case scroll when newline + and cursor off top edge of display */ + hb_gtScroll( 0, 0, iMaxRow, iMaxCol, 1, 0 ); + } + hb_gtSetPos( iRow, iCol ); ldisp = FALSE; + lnewline = FALSE; } if( rc ) break; diff --git a/harbour/source/rtl/set.c b/harbour/source/rtl/set.c index 7835c4c579..989301adf0 100644 --- a/harbour/source/rtl/set.c +++ b/harbour/source/rtl/set.c @@ -33,9 +33,22 @@ * */ +/* + * The following parts are Copyright of the individual authors. + * www - http://www.harbour-project.org + * + * Copyright 1999 Jose Lalin + * HB_DEFPATH() and HB___DEFPATH() + * + * See doc/license.txt for licensing terms. + * + */ + /* * ChangeLog: * + * V 1.83 David G. Holm Added DEFPATH() and __DEFPATH() + * provided by Jose Lalin. * V 1.81 David G. Holm Corrected _SET_CURSOR to use the GT API * when available. * V 1.70 David G. Holm Corrected _SET_COLOR case to only use @@ -526,7 +539,7 @@ HARBOUR HB___SETCENTURY( void ) * a number. Only the display format is affected. * _SET_DEFAULT * Sets the default directory in which to open, create and - * check for files. Defaults to the current directory. + * check for files. Defaults to current directory (blank). * _SET_DELETED | * If enabled, deleted records will be processed. If * disabled, which is the default, deleted records will @@ -1004,3 +1017,16 @@ void hb_setRelease( void ) hb_set.HB_SET_TYPEAHEAD = -1; hb_inkeyReset( TRUE ); /* Free keyboard typeahead buffer */ } + +HARBOUR HB_DEFPATH( void ) +{ + if( hb_set.HB_SET_DEFAULT ) + hb_retc( hb_set.HB_SET_DEFAULT ); + else + hb_retc( "" ); +} + +HARBOUR HB___DEFPATH( void ) +{ + HB_DEFPATH(); +}