diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 55e5d5ee9c..647cd2f006 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,34 @@ +19990902--01:44 GMT+1 Victor Szel + * source/rtl/filesys.c + include/filesys.h + - For speed reasons the hb_fsRead/Write() functions were set back to use + USHORT, they are again Clipper compatible, and don't have the overhead + of the long buffer support, since for most cases it's not needed. + + hb_fsReadLarge() and hb_fsWriteLarge() API functions added, which support + the very long buffer lengths (ULONG_MAX). FREADSTR() is using the large + read right now. + ! hb_fsWriteLarge() infinite loop on error fixed (?) Paul ? + + TOFIX: added to hb_fsFNameMerge() (related to buffer overrun). + * source/rtl/console.c + source/rtl/set.c + include/set.h + + Changed to use the Filesys API instead of calling the platform dependent + file handling functions. + ! hb_err*() caller now expect E_BREAK, too. + ! hb_setRelease() called close_binary() instead of close_text() for + hb_set_extrahan. Fixed. + - Removed a bunch of (now) unneeded include files and OS branched. + Source look kind of clean now. + * config/rules.cf + make_tpl.* + + Added the L_USR variable, to make it possible to pass custom parameters + to the linker. Some platform/compiler combinations need to add support + for this manually: DOS/BCC31, DOS/WATCOM, WIN32/BCC32, WIN32/ICC + * source/rtl/itemapi.c + ! Some formatting errors removed. + * tests/working/rtl_test.prg + * Small corrections. + 19990901-20:34 GMT+1 Victor Szel * source/vm/initsymb.c + HB_LOCK pointer added. diff --git a/harbour/config/rules.cf b/harbour/config/rules.cf index 2205687b5d..1786c8c2c2 100644 --- a/harbour/config/rules.cf +++ b/harbour/config/rules.cf @@ -25,7 +25,7 @@ HB_FLAGS = -n -q -I$(TOP) -I$(HB_INC_COMPILE) # The rule to link an executable. ifeq ($(LD_RULE),) # Use default rule if architecture/compiler specific rule is not defined -LD_RULE = $(LD) $(CFLAGS) $(LD_OUT)$@ $^ $(LDFLAGS) $(LINKLIBS) +LD_RULE = $(LD) $(CFLAGS) $(LD_OUT)$@ $^ $(LDFLAGS) $(L_USR) $(LINKLIBS) endif # Eliminate these rules. diff --git a/harbour/include/filesys.h b/harbour/include/filesys.h index a016f47c5f..8c92de8426 100644 --- a/harbour/include/filesys.h +++ b/harbour/include/filesys.h @@ -77,12 +77,14 @@ extern BOOL hb_fsLock ( FHANDLE hFileHandle, ULONG ulStart, ULONG ulLength, USHORT uiMode ); extern BOOL hb_fsMkDir ( BYTE * pDirName ); extern FHANDLE hb_fsOpen ( BYTE * pFilename, USHORT uiFlags ); -extern ULONG hb_fsRead ( FHANDLE hFileHandle, BYTE * pBuff, ULONG ulCount ); +extern USHORT hb_fsRead ( FHANDLE hFileHandle, BYTE * pBuff, USHORT ulCount ); +extern ULONG hb_fsReadLarge ( FHANDLE hFileHandle, BYTE * pBuff, ULONG ulCount ); extern BOOL hb_fsRmDir ( BYTE * pDirName ); extern int hb_fsRename ( BYTE * pOldName, BYTE * pNewName ); extern ULONG hb_fsSeek ( FHANDLE hFileHandle, LONG lOffset, USHORT uiMode ); extern void hb_fsSetMode ( FHANDLE hFileHandle, USHORT uiMode ); -extern ULONG hb_fsWrite ( FHANDLE hFileHandle, BYTE * pBuff, ULONG ulCount ); +extern USHORT hb_fsWrite ( FHANDLE hFileHandle, BYTE * pBuff, USHORT ulCount ); +extern ULONG hb_fsWriteLarge ( FHANDLE hFileHandle, BYTE * pBuff, ULONG ulCount ); extern PHB_FNAME hb_fsFNameSplit ( char * szFilename ); /* Split given filename into path, name and extension */ extern char * hb_fsFNameMerge ( char * szFileName, PHB_FNAME pFileName ); /* This function joins path, name and extension into a string with a filename */ diff --git a/harbour/include/set.h b/harbour/include/set.h index 28265d7ac0..451d0f273e 100644 --- a/harbour/include/set.h +++ b/harbour/include/set.h @@ -77,6 +77,7 @@ #define HB_SET_H_ #include "hbdefs.h" +#include "filesys.h" typedef enum { @@ -194,10 +195,10 @@ typedef struct } HB_set_struct; extern HB_set_struct hb_set; -extern BOOL hb_set_century; -extern int hb_set_althan; -extern int hb_set_extrahan; -extern int hb_set_printhan; +extern BOOL hb_set_century; +extern FHANDLE hb_set_althan; +extern FHANDLE hb_set_extrahan; +extern FHANDLE hb_set_printhan; extern void hb_setInitialize( void ); extern void hb_setRelease( void ); diff --git a/harbour/make_tpl.bat b/harbour/make_tpl.bat index f5c909f862..ce9ea9c4dd 100644 --- a/harbour/make_tpl.bat +++ b/harbour/make_tpl.bat @@ -57,8 +57,9 @@ set HB_COMPILER=djgpp rem --------------------------------------------------------------- rem Fine tuning the compiler parameters for "all" command: -set C_USR= set PRG_USR= +set C_USR= +set L_USR= rem --------------------------------------------------------------- rem Start the GNU make system diff --git a/harbour/make_tpl.cmd b/harbour/make_tpl.cmd index 070401160e..1feb54a730 100644 --- a/harbour/make_tpl.cmd +++ b/harbour/make_tpl.cmd @@ -57,8 +57,9 @@ set HB_COMPILER=gcc rem --------------------------------------------------------------- rem Fine tuning the compiler parameters for "all" command: -set C_USR= set PRG_USR= +set C_USR= +set L_USR= rem --------------------------------------------------------------- rem Start the GNU make system diff --git a/harbour/make_tpl.sh b/harbour/make_tpl.sh index 6dadcc8e82..8597bbcfdb 100644 --- a/harbour/make_tpl.sh +++ b/harbour/make_tpl.sh @@ -57,8 +57,9 @@ export HB_COMPILER=gcc # --------------------------------------------------------------- # Fine tuning the compiler parameters for "all" command: -export C_USR= export PRG_USR= +export C_USR= +export L_USR= # --------------------------------------------------------------- # Start the GNU make system diff --git a/harbour/source/rtl/console.c b/harbour/source/rtl/console.c index 0d22321186..2f9d66abb9 100644 --- a/harbour/source/rtl/console.c +++ b/harbour/source/rtl/console.c @@ -327,7 +327,7 @@ static void hb_altout( char * pStr, ULONG len ) write_len = count; count = 0; } - write( hb_set_althan, pPtr, write_len ); + hb_fsWrite( hb_set_althan, pPtr, write_len ); pPtr += write_len; } } @@ -349,7 +349,7 @@ static void hb_altout( char * pStr, ULONG len ) write_len = count; count = 0; } - write( hb_set_extrahan, pPtr, write_len ); + hb_fsWrite( hb_set_extrahan, pPtr, write_len ); pPtr += write_len; } } @@ -371,7 +371,7 @@ static void hb_altout( char * pStr, ULONG len ) write_len = count; count = 0; } - write( hb_set_printhan, pPtr, write_len ); + hb_fsWrite( hb_set_printhan, pPtr, write_len ); pPtr += write_len; } if( len + s_uiPCol > USHRT_MAX ) s_uiPCol = USHRT_MAX; @@ -400,7 +400,7 @@ static void hb_devout( char * pStr, ULONG len ) write_len = count; count = 0; } - write( hb_set_printhan, pPtr, write_len ); + hb_fsWrite( hb_set_printhan, pPtr, write_len ); pPtr += write_len; } if( len + s_uiPCol > USHRT_MAX ) s_uiPCol = USHRT_MAX; @@ -473,13 +473,19 @@ void hb_devpos( WORD row, WORD col ) { if( row < s_uiPRow ) { - write( hb_set_printhan, "\x0C", 1 ); + hb_fsWrite( hb_set_printhan, "\x0C", 1 ); s_uiPRow = s_uiPCol = 0; } - for( count = s_uiPRow; count < row; count++ ) write( hb_set_printhan, s_szCrLf, CRLF_BUFFER_LEN-1 ); + + for( count = s_uiPRow; count < row; count++ ) + hb_fsWrite( hb_set_printhan, s_szCrLf, CRLF_BUFFER_LEN-1 ); + if( row > s_uiPRow ) s_uiPCol = 0; col += hb_set.HB_SET_MARGIN; - for( count = s_uiPCol; count < col; count++ ) write( hb_set_printhan, " ", 1 ); + + for( count = s_uiPCol; count < col; count++ ) + hb_fsWrite( hb_set_printhan, " ", 1 ); + s_uiPRow = row; s_uiPCol = col; } @@ -533,7 +539,8 @@ HARBOUR HB_QOUT( void ) s_uiPRow++; s_uiPCol = hb_set.HB_SET_MARGIN; count = s_uiPCol; - while( count-- > 0 ) write( hb_set_printhan, " ", 1 ); + while( count-- > 0 ) + hb_fsWrite( hb_set_printhan, " ", 1 ); } HB_QQOUT(); @@ -647,7 +654,7 @@ HARBOUR HB___EJECT( void ) /* Ejects the current page from the printer */ { if( hb_stricmp( hb_set.HB_SET_DEVICE, "PRINTER" ) == 0 && hb_set_printhan >= 0 ) { - write( hb_set_printhan, "\x0C\x0D", 2 ); + hb_fsWrite( hb_set_printhan, "\x0C\x0D", 2 ); s_uiPRow = s_uiPCol = 0; } } diff --git a/harbour/source/rtl/filesys.c b/harbour/source/rtl/filesys.c index b50d5884af..22cd9e17ff 100644 --- a/harbour/source/rtl/filesys.c +++ b/harbour/source/rtl/filesys.c @@ -5,6 +5,9 @@ /* Harbour Project source code http://www.Harbour-Project.org/ The following functions are Copyright 1999 Victor Szel : + hb_fsSetMode() + hb_fsReadLarge() + hb_fsWriteLarge() HB_CURDIR() HB_DIRCHANGE() HB_MAKEDIR() @@ -386,9 +389,51 @@ void hb_fsSetMode( FHANDLE hFileHandle, USHORT uiMode ) } -/* NOTE: CA-Clipper uses USHORT instead of ULONG here. */ +USHORT hb_fsRead( FHANDLE hFileHandle, BYTE * pBuff, USHORT uiCount ) +{ + USHORT uiRead; -ULONG hb_fsRead( FHANDLE hFileHandle, BYTE * pBuff, ULONG ulCount ) +#if defined(HAVE_POSIX_IO) || defined(_MSC_VER) + + errno = 0; + uiRead = read( hFileHandle, pBuff, uiCount ); + s_uiErrorLast = errno; + if( uiRead == ( USHORT )-1 ) + uiRead = 0; + +#else + + uiRead = 0; + s_uiErrorLast = FS_ERROR; + +#endif + + return uiRead; +} + +USHORT hb_fsWrite( FHANDLE hFileHandle, BYTE * pBuff, USHORT uiCount ) +{ + USHORT uiWritten; + +#if defined(HAVE_POSIX_IO) || defined(_MSC_VER) + + errno = 0; + uiWritten = write( hFileHandle, pBuff, uiCount ); + s_uiErrorLast = errno; + if( uiWritten == ( USHORT )-1 ) + uiWritten = 0; + +#else + + uiWritten = 0; + s_uiErrorLast = FS_ERROR; + +#endif + + return uiWritten; +} + +ULONG hb_fsReadLarge( FHANDLE hFileHandle, BYTE * pBuff, ULONG ulCount ) { ULONG ulReadTotal = 0; @@ -404,9 +449,8 @@ ULONG hb_fsRead( FHANDLE hFileHandle, BYTE * pBuff, ULONG ulCount ) ulReadTotal += ( ULONG ) uiRead; - if( uiRead < ulCount - ulReadTotal ) + if( uiRead < ( USHORT ) ( ulCount - ulReadTotal ) ) break; - } s_uiErrorLast = errno; @@ -419,9 +463,7 @@ ULONG hb_fsRead( FHANDLE hFileHandle, BYTE * pBuff, ULONG ulCount ) return ulReadTotal; } -/* NOTE: CA-Clipper uses USHORT instead of ULONG here. */ - -ULONG hb_fsWrite( FHANDLE hFileHandle, BYTE * pBuff, ULONG ulCount ) +ULONG hb_fsWriteLarge( FHANDLE hFileHandle, BYTE * pBuff, ULONG ulCount ) { ULONG ulWrittenTotal = 0; @@ -436,6 +478,9 @@ ULONG hb_fsWrite( FHANDLE hFileHandle, BYTE * pBuff, ULONG ulCount ) break; ulWrittenTotal += ( ULONG ) uiWritten; + + if( uiWritten < ( USHORT ) ( ulCount - ulWrittenTotal ) ) + break; } s_uiErrorLast = errno; @@ -995,7 +1040,7 @@ HARBOUR HB_FREADSTR( void ) BYTE * buffer = ( BYTE * ) hb_xgrab( ulToRead + 1 ); ULONG ulRead; - ulRead = hb_fsRead( ( FHANDLE ) hb_parni( 1 ), buffer, ulToRead ); + ulRead = hb_fsReadLarge( ( FHANDLE ) hb_parni( 1 ), buffer, ulToRead ); buffer[ ulRead ] = '\0'; @@ -1319,6 +1364,8 @@ PHB_FNAME hb_fsFNameSplit( char * szFilename ) return pName; } +/* TOFIX: Check not to overrun the _POSIX_PATH_MAX buffer size. */ + /* This function joins path, name and extension into a string with a filename */ char * hb_fsFNameMerge( char * szFileName, PHB_FNAME pFileName ) { @@ -1351,7 +1398,7 @@ char * hb_fsFNameMerge( char * szFileName, PHB_FNAME pFileName ) { int iLen = strlen( szFileName ); - if( !( pFileName->szExtension[ 0 ] == '.' || szFileName[ iLen-1 ] == '.') ) + if( !( pFileName->szExtension[ 0 ] == '.' || szFileName[ iLen - 1 ] == '.') ) { /* add extension separator only when extansion doesn't contain it */ szFileName[ iLen++ ] = '.'; diff --git a/harbour/source/rtl/itemapi.c b/harbour/source/rtl/itemapi.c index 44f651b366..848cf30cdc 100644 --- a/harbour/source/rtl/itemapi.c +++ b/harbour/source/rtl/itemapi.c @@ -248,7 +248,7 @@ ULONG hb_itemCopyC( PHB_ITEM pItem, char * szBuffer, ULONG ulLen ) return 0; } -BOOL hb_itemFreeC( char *szText ) +BOOL hb_itemFreeC( char * szText ) { BOOL bResult = FALSE; @@ -261,7 +261,7 @@ BOOL hb_itemFreeC( char *szText ) return bResult; } -char *hb_itemGetDS( PHB_ITEM pItem, char *szDate ) +char * hb_itemGetDS( PHB_ITEM pItem, char * szDate ) { if( pItem && IS_DATE( pItem ) ) { @@ -271,9 +271,7 @@ char *hb_itemGetDS( PHB_ITEM pItem, char *szDate ) hb_dateStrPut( szDate, lDay, lMonth, lYear ); } else - { memset( szDate, ' ', 8 ); - } return szDate; } @@ -284,10 +282,17 @@ BOOL hb_itemGetL( PHB_ITEM pItem ) { switch( pItem->type ) { - case IT_LOGICAL: return pItem->item.asLogical.value; - case IT_INTEGER: return pItem->item.asInteger.value != 0; - case IT_LONG: return pItem->item.asLong.value != 0; - case IT_DOUBLE: return pItem->item.asDouble.value != 0.0; + case IT_LOGICAL: + return pItem->item.asLogical.value; + + case IT_INTEGER: + return pItem->item.asInteger.value != 0; + + case IT_LONG: + return pItem->item.asLong.value != 0; + + case IT_DOUBLE: + return pItem->item.asDouble.value != 0.0; } } @@ -300,9 +305,14 @@ double hb_itemGetND( PHB_ITEM pItem ) { switch( pItem->type ) { - case IT_DOUBLE: return pItem->item.asDouble.value; - case IT_INTEGER: return ( double ) pItem->item.asInteger.value; - case IT_LONG: return ( double ) pItem->item.asLong.value; + case IT_DOUBLE: + return pItem->item.asDouble.value; + + case IT_INTEGER: + return ( double ) pItem->item.asInteger.value; + + case IT_LONG: + return ( double ) pItem->item.asLong.value; } } @@ -315,10 +325,17 @@ long hb_itemGetNL( PHB_ITEM pItem ) { switch( pItem->type ) { - case IT_LONG: return pItem->item.asLong.value; - case IT_INTEGER: return ( long ) pItem->item.asInteger.value; - case IT_DOUBLE: return ( long ) pItem->item.asDouble.value; - case IT_DATE: return pItem->item.asDate.value; + case IT_LONG: + return pItem->item.asLong.value; + + case IT_INTEGER: + return ( long ) pItem->item.asInteger.value; + + case IT_DOUBLE: + return ( long ) pItem->item.asDouble.value; + + case IT_DATE: + return pItem->item.asDate.value; } } @@ -333,7 +350,7 @@ PHB_ITEM hb_itemReturn( PHB_ITEM pItem ) return pItem; } -PHB_ITEM hb_itemPutDS( PHB_ITEM pItem, char *szDate ) +PHB_ITEM hb_itemPutDS( PHB_ITEM pItem, char * szDate ) { long lDay, lMonth, lYear; @@ -389,7 +406,7 @@ PHB_ITEM hb_itemPutNL( PHB_ITEM pItem, long lNumber ) pItem->type = IT_LONG; pItem->item.asLong.length = 10; - pItem->item.asLong.value = lNumber; + pItem->item.asLong.value = lNumber; return pItem; } @@ -401,23 +418,23 @@ void hb_itemGetNLen( PHB_ITEM pItem, WORD * pwWidth, WORD * pwDecimal ) switch( pItem->type ) { case IT_DOUBLE: - if( pwWidth ) * pwWidth = pItem->item.asDouble.length; - if( pwDecimal ) * pwDecimal = pItem->item.asDouble.decimal; + if( pwWidth ) *pwWidth = pItem->item.asDouble.length; + if( pwDecimal ) *pwDecimal = pItem->item.asDouble.decimal; break; case IT_LONG: - if( pwWidth ) * pwWidth = pItem->item.asLong.length; - if( pwDecimal ) * pwDecimal = 0; + if( pwWidth ) *pwWidth = pItem->item.asLong.length; + if( pwDecimal ) *pwDecimal = 0; break; case IT_INTEGER: - if( pwWidth ) * pwWidth = pItem->item.asInteger.length; - if( pwDecimal ) * pwDecimal = 0; + if( pwWidth ) *pwWidth = pItem->item.asInteger.length; + if( pwDecimal ) *pwDecimal = 0; break; default: - if( pwWidth ) * pwWidth = 0; - if( pwDecimal ) * pwDecimal = 0; + if( pwWidth ) *pwWidth = 0; + if( pwDecimal ) *pwDecimal = 0; break; } } @@ -453,8 +470,11 @@ ULONG hb_itemSize( PHB_ITEM pItem ) { switch( pItem->type ) { - case IT_ARRAY: return hb_arrayLen( pItem ); - case IT_STRING: return pItem->item.asString.length; + case IT_ARRAY: + return hb_arrayLen( pItem ); + + case IT_STRING: + return pItem->item.asString.length; } } @@ -576,41 +596,46 @@ int hb_itemStrCmp( PHB_ITEM pFirst, PHB_ITEM pSecond, BOOL bForceExact ) char * szSecond = pSecond->item.asString.value; ULONG lLenFirst = pFirst->item.asString.length; ULONG lLenSecond = pSecond->item.asString.length; - long lMinLen; - long lCounter; - int iRet = 0; /* Current status */ + LONG lMinLen; + LONG lCounter; + int iRet = 0; /* Current status */ - if( hb_set.HB_SET_EXACT && ! bForceExact ) - { /* SET EXACT ON and not using == */ - /* Don't include trailing spaces */ - while( lLenFirst > 0 && szFirst[ lLenFirst - 1 ] == ' ') lLenFirst--; - while( lLenSecond > 0 && szSecond[ lLenSecond - 1 ] == ' ') lLenSecond--; + if( hb_set.HB_SET_EXACT && !bForceExact ) + { + /* SET EXACT ON and not using == */ + /* Don't include trailing spaces */ + while( lLenFirst > 0 && szFirst[ lLenFirst - 1 ] == ' ' ) lLenFirst--; + while( lLenSecond > 0 && szSecond[ lLenSecond - 1 ] == ' ' ) lLenSecond--; } lMinLen = lLenFirst < lLenSecond ? lLenFirst : lLenSecond; - if( lMinLen ) /* One of the strings is empty */ + /* One of the strings is empty */ + if( lMinLen ) { for( lCounter = 0; lCounter < lMinLen && !iRet; lCounter++ ) { - if( *szFirst != *szSecond ) /* Difference found */ + /* Difference found */ + if( *szFirst != *szSecond ) iRet = ( *szFirst < *szSecond ) ? -1 : 1; - else /* TODO : #define some constants*/ + else /* TODO : #define some constants */ { - szFirst++; - szSecond++; + szFirst++; + szSecond++; } } if( hb_set.HB_SET_EXACT || bForceExact || lLenSecond > lCounter ) - { /* Force an exact comparison */ - if( ! iRet && lLenFirst != lLenSecond ) - /* If length is different ! */ - iRet = ( lLenFirst < lLenSecond ) ? -1 : 1; + { + /* Force an exact comparison */ + if( !iRet && lLenFirst != lLenSecond ) + /* If length is different ! */ + iRet = ( lLenFirst < lLenSecond ) ? -1 : 1; } } else { - if( lLenFirst != lLenSecond ) /* Both empty ? */ + /* Both empty ? */ + if( lLenFirst != lLenSecond ) { if( hb_set.HB_SET_EXACT || bForceExact ) iRet = ( lLenFirst < lLenSecond ) ? -1 : 1; @@ -618,7 +643,8 @@ int hb_itemStrCmp( PHB_ITEM pFirst, PHB_ITEM pSecond, BOOL bForceExact ) iRet = ( lLenSecond == 0 ) ? 0 : -1; } else - iRet = 0; /* Both empty => Equal ! */ + /* Both empty => Equal ! */ + iRet = 0; } return iRet; diff --git a/harbour/source/rtl/set.c b/harbour/source/rtl/set.c index b0d7bbd2fd..ab318c9e3d 100644 --- a/harbour/source/rtl/set.c +++ b/harbour/source/rtl/set.c @@ -29,6 +29,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit their web site at http://www.gnu.org/). + V 1.64 Victor Szel Converted to use the FS API. + hb_err*() handles E_BREAK. + extrahan closing mode on exit fixed. V 1.62 Paul Tucker Converted HB_SET_DEBUG back to Logical. Clipper 5.3 docs are incorrect on this. V 1.51 Victor Szel #include changed to #include "x". @@ -150,40 +153,18 @@ V 1.0 David G. Holm Initial version. */ -#if defined(__GNUC__) - #include - #include - #if defined(__DJGPP__) - #include - #endif -#else - #ifndef __MPW__ - #include - #endif -#endif - -#include -#ifndef __MPW__ - #include -#endif -#include - #include #include "extend.h" #include "errorapi.h" +#include "filesys.h" #include "set.h" #include "inkey.h" -#ifndef O_BINARY - #define O_BINARY 0 /* O_BINARY not defined on Linux */ -#endif - HB_set_struct hb_set; - -BOOL hb_set_century; -int hb_set_althan; -int hb_set_extrahan; -int hb_set_printhan; +BOOL hb_set_century; +FHANDLE hb_set_althan; +FHANDLE hb_set_extrahan; +FHANDLE hb_set_printhan; static BOOL set_logical( PHB_ITEM pItem ) { @@ -227,103 +208,86 @@ static char * set_string( PHB_ITEM pItem, char * old_str ) { /* Limit size of SET strings to 64K, truncating if source is longer */ ULONG size = pItem->item.asString.length; + if( size > USHRT_MAX ) size = USHRT_MAX; + if( old_str ) string = ( char * ) hb_xrealloc( old_str, size + 1 ); else string = ( char * ) hb_xgrab( size + 1 ); + memcpy( string, pItem->item.asString.value, size ); string[ size ] = '\0'; } - else string = old_str; + else + string = old_str; return string; } -static void close_binary( int handle ) +static void close_binary( FHANDLE handle ) { -#if defined(OS_UNIX_COMPATIBLE) - fchmod( handle, S_IRUSR | S_IWUSR ); -#endif - close( handle ); + if( handle != FS_ERROR ) + hb_fsClose( handle ); } -static void close_text( int handle ) +static void close_text( FHANDLE handle ) { -#if defined(OS_UNIX_COMPATIBLE) - fchmod( handle, S_IRUSR | S_IWUSR ); -#else - write( handle, "\x1A", 1 ); -#endif - close( handle ); + if( handle != FS_ERROR ) + { + #if ! defined(OS_UNIX_COMPATIBLE) + hb_fsWrite( handle, "\x1A", 1 ); + #endif + hb_fsClose( handle ); + } } -static int open_handle( char * file_name, BOOL bMode, char * def_ext, HB_set_enum set_specifier ) +static FHANDLE open_handle( char * file_name, BOOL bMode, char * def_ext, HB_set_enum set_specifier ) { -#ifdef __MPW__ -/* TODO: not implemented yet */ - return -1; -#else - int handle; - BOOL bExt = FALSE, bSep = FALSE; - ULONG index; + FHANDLE handle; + PHB_FNAME pFilename; char path[ _POSIX_PATH_MAX + 1 ]; - /* Check to see if the file name has an extension? */ - for( index = strlen( file_name ); index; index-- ) - { - switch ( file_name[ index ] ) - { - case '.': - if( ! bSep ) bExt = TRUE; /* Extension found before separator */ - break; - case '\\': - case '/': - case ':': - bSep = TRUE; /* Path or drive separator found */ - } - } - /* Note: strlen (path) is guaranteed to be <= _POSIX_PATH_MAX from this point */ - if( bSep ) path[ 0 ] = '\0'; /* File name includes a drive letter or path */ - else if( hb_set.HB_SET_DEFAULT ) - { - /* If no path in file name, use default path */ - strncpy( path, hb_set.HB_SET_DEFAULT, _POSIX_PATH_MAX ); - path[ _POSIX_PATH_MAX ] = '\0'; - } - /* Add the file name */ - strncat( path, file_name, _POSIX_PATH_MAX - strlen( path ) ); - path[ _POSIX_PATH_MAX ] = '\0'; - if( def_ext && ! bExt ) - { - /* If the file name does not have an extension (no period following the last - path or drive separator), add the default file extension */ - strncat( path, def_ext, _POSIX_PATH_MAX - strlen( path ) ); - path[ _POSIX_PATH_MAX ] = '\0'; - } + /* Create full filename */ + + pFilename = hb_fsFNameSplit( file_name ); + + if( ! pFilename->szPath && hb_set.HB_SET_DEFAULT ) + pFilename->szPath = hb_set.HB_SET_DEFAULT; + if( ! pFilename->szExtension && def_ext ) + pFilename->szExtension = def_ext; + + hb_fsFNameMerge( path, pFilename ); + hb_xfree( pFilename ); /* Open the file either in append (bMode) or truncate mode (!bMode), but always use binary mode */ - while( ( handle = open( path, O_BINARY | O_WRONLY | O_CREAT | ( bMode ? O_APPEND : O_TRUNC ), S_IWRITE ) ) == -1 ) + + /* QUESTION: What sharing mode does Clipper use ? [vszel] */ + + while( ( handle = ( bMode ? hb_fsOpen( path, FO_WRITE | FO_DENYWRITE ) : + hb_fsCreate( path, FC_NORMAL ) ) ) == FS_ERROR ) { + WORD wResult; + + /* NOTE: using switch() here will result in a compiler warning */ if( set_specifier == HB_SET_ALTFILE ) - { - if( hb_errRT_TERM( EG_CREATE, 2013, NULL, path, errno, EF_CANDEFAULT | EF_CANRETRY ) == E_DEFAULT ) - break; - } + wResult = hb_errRT_TERM( EG_CREATE, 2013, NULL, path, hb_fsError(), EF_CANDEFAULT | EF_CANRETRY ); else if( set_specifier == HB_SET_PRINTFILE ) - { - if( hb_errRT_TERM( EG_CREATE, 2014, NULL, path, errno, EF_CANDEFAULT | EF_CANRETRY ) == E_DEFAULT ) - break; - } + wResult = hb_errRT_TERM( EG_CREATE, 2014, NULL, path, hb_fsError(), EF_CANDEFAULT | EF_CANRETRY ); else if( set_specifier == HB_SET_EXTRAFILE ) - { - if( hb_errRT_TERM( EG_CREATE, 2015, NULL, path, errno, EF_CANDEFAULT | EF_CANRETRY ) == E_DEFAULT ) - break; - } + wResult = hb_errRT_TERM( EG_CREATE, 2015, NULL, path, hb_fsError(), EF_CANDEFAULT | EF_CANRETRY ); + else + wResult = E_DEFAULT; + + if( wResult == E_DEFAULT || wResult == E_BREAK ) + break; } + /* If append mode, set the file pointer to EOF */ + if( handle != FS_ERROR ) + hb_fsSeek( handle, 0, FS_END ); + return handle; -#endif } HARBOUR HB_SETCANCEL( void ) @@ -682,7 +646,7 @@ HARBOUR HB_SET( void ) else bFlag = FALSE; if( args > 1 ) { - if( hb_set_althan >= 0 ) close_text( hb_set_althan ); + close_text( hb_set_althan ); if( hb_set.HB_SET_ALTFILE && strlen( hb_set.HB_SET_ALTFILE ) > 0 ) hb_set_althan = open_handle( hb_set.HB_SET_ALTFILE, bFlag, ".txt", HB_SET_ALTFILE ); } @@ -801,7 +765,7 @@ HARBOUR HB_SET( void ) else bFlag = FALSE; if( args > 1 ) { - if( hb_set_extrahan >= 0 ) close_text( hb_set_extrahan ); + close_text( hb_set_extrahan ); if( hb_set.HB_SET_EXTRAFILE && strlen( hb_set.HB_SET_EXTRAFILE ) > 0 ) hb_set_extrahan = open_handle( hb_set.HB_SET_EXTRAFILE, bFlag, ".prn", HB_SET_EXTRAFILE ); } @@ -859,7 +823,7 @@ HARBOUR HB_SET( void ) else bFlag = FALSE; if( args > 1 ) { - if( hb_set_printhan >= 0 ) close_binary( hb_set_printhan ); + close_binary( hb_set_printhan ); if( hb_set.HB_SET_PRINTFILE && strlen( hb_set.HB_SET_PRINTFILE ) > 0 ) hb_set_printhan = open_handle( hb_set.HB_SET_PRINTFILE, bFlag, ".prn", HB_SET_PRINTFILE ); } @@ -907,9 +871,9 @@ HARBOUR HB_SET( void ) void hb_setInitialize( void ) { hb_set_century = FALSE; - hb_set_althan = -1; - hb_set_extrahan = -1; - hb_set_printhan = -1; + hb_set_althan = FS_ERROR; + hb_set_extrahan = FS_ERROR; + hb_set_printhan = FS_ERROR; hb_set.HB_SET_ALTERNATE = FALSE; hb_set.HB_SET_ALTFILE = NULL; hb_set.HB_SET_BELL = FALSE; @@ -960,9 +924,9 @@ void hb_setInitialize( void ) void hb_setRelease( void ) { - if( hb_set_althan != -1 ) close_text( hb_set_althan ); - if( hb_set_extrahan != -1 ) close_binary( hb_set_extrahan ); - if( hb_set_printhan != -1 ) close_binary( hb_set_printhan ); + close_text( hb_set_althan ); + close_text( hb_set_extrahan ); + close_binary( hb_set_printhan ); if( hb_set.HB_SET_ALTFILE ) hb_xfree( hb_set.HB_SET_ALTFILE ); if( hb_set.HB_SET_DATEFORMAT ) hb_xfree( hb_set.HB_SET_DATEFORMAT ); diff --git a/harbour/tests/working/rtl_test.prg b/harbour/tests/working/rtl_test.prg index 1481036db8..36d8321d71 100644 --- a/harbour/tests/working/rtl_test.prg +++ b/harbour/tests/working/rtl_test.prg @@ -325,7 +325,7 @@ FUNCTION Main( cPar1 ) #ifndef __HARBOUR__ TEST_LINE( "AA" $ 1 , "E BASE 1109 Argument error $ F:S" ) #endif - TEST_LINE( lcString $ 1 , "E BASE 1109 Argument error $ F:S" ) + TEST_LINE( lcString $ 1 , "E BASE 1109 Argument error $ F:S" ) TEST_LINE( 1 $ "AA" , "E BASE 1109 Argument error $ F:S" ) IF TEST_OPT_Z()