From d039f3bec71a5e7df7cce5051c3b424ae83b7ba6 Mon Sep 17 00:00:00 2001 From: Przemyslaw Czerpak Date: Thu, 21 May 2009 09:10:41 +0000 Subject: [PATCH] 2009-05-21 11:19 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/source/rtl/filebuf.c ! refuse to share file handles if they were open in different mode TODO: add support for keeping more then one handle for single file open and allow such combinations. * harbour/source/rtl/hbffind.c % optimized *nix version of hb_fsFind*() * harbour/utils/hbmk2/hbmk2.prg ! fixed compilation on non Windows platforms (unused variable warning) * harbour/include/hbset.h * harbour/source/vm/set.c + added new function hb_setGetPrinterHandle() which allows to open closed printer port ! do not force opening default port after SET PRINTER TO "" but delay the initialization untill other code does not call hb_setGetPrinterHandle() ! fixed filename returned by _SET_PRINTFILE, _SET_ALTFILE, _SET_EXTRAFILE ! fixed dpossible resource leaks whne _SET_*FILE is called recurisvely for user error block ! fixed _SET_*FILE settings to not accept files which cannot be open (just like in Clipper) * harbour/source/rtl/console.c * use hb_setGetPrinterHandle() to access printer handler --- harbour/ChangeLog | 28 +++ harbour/include/hbset.h | 11 +- harbour/source/rtl/console.c | 45 ++-- harbour/source/rtl/filebuf.c | 30 ++- harbour/source/rtl/hbffind.c | 20 +- harbour/source/vm/set.c | 436 ++++++++++++++++------------------ harbour/utils/hbmk2/hbmk2.prg | 4 + 7 files changed, 293 insertions(+), 281 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index c19256bc10..c7613a6844 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,34 @@ past entries belonging to these authors: Viktor Szakats. */ +2009-05-21 11:19 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/source/rtl/filebuf.c + ! refuse to share file handles if they were open in different mode + TODO: add support for keeping more then one handle for single file + open and allow such combinations. + + * harbour/source/rtl/hbffind.c + % optimized *nix version of hb_fsFind*() + + * harbour/utils/hbmk2/hbmk2.prg + ! fixed compilation on non Windows platforms (unused variable warning) + + * harbour/include/hbset.h + * harbour/source/vm/set.c + + added new function hb_setGetPrinterHandle() which allows to open + closed printer port + ! do not force opening default port after SET PRINTER TO "" + but delay the initialization untill other code does not call + hb_setGetPrinterHandle() + ! fixed filename returned by _SET_PRINTFILE, _SET_ALTFILE, _SET_EXTRAFILE + ! fixed dpossible resource leaks whne _SET_*FILE is called recurisvely + for user error block + ! fixed _SET_*FILE settings to not accept files which cannot be open + (just like in Clipper) + + * harbour/source/rtl/console.c + * use hb_setGetPrinterHandle() to access printer handler + 2009-05-21 08:53 UTC+0200 Viktor Szakats (harbour.01 syenar hu) * utils/hbmk2/hbmk2.prg + Added automatic configuration for bcc compiler. This kicks in diff --git a/harbour/include/hbset.h b/harbour/include/hbset.h index a88b58d015..69f90edbc4 100644 --- a/harbour/include/hbset.h +++ b/harbour/include/hbset.h @@ -145,8 +145,9 @@ typedef enum typedef struct { /* Lower case members are indirectly related to a SET */ - HB_FHANDLE hb_set_althan; BOOL hb_set_century; + BOOL hb_set_prndevice; + HB_FHANDLE hb_set_althan; HB_FHANDLE hb_set_extrahan; HB_FHANDLE hb_set_printhan; HB_PATHNAMES * hb_set_path; @@ -233,6 +234,10 @@ typedef void * PHB_SET_STRUCT; #define HB_SET_CASE_LOWER 1 #define HB_SET_CASE_UPPER 2 +#define HB_SET_PRN_ANY 0 +#define HB_SET_PRN_CON 1 +#define HB_SET_PRN_DEV 2 + #define HB_SET_DBFLOCK_DEFAULT 0 #define HB_SET_DBFLOCK_CLIP 1 #define HB_SET_DBFLOCK_CL53 2 @@ -259,11 +264,13 @@ extern HB_EXPORT BOOL hb_setSetItem2( HB_set_enum set_specifier, PHB_ITEM extern HB_EXPORT HB_PATHNAMES * hb_setGetFirstSetPath( void ); -extern HB_EXPORT HB_FHANDLE hb_setGetAltHan( void ); extern HB_EXPORT BOOL hb_setGetCentury( void ); extern HB_EXPORT BOOL hb_setSetCentury( BOOL ); + +extern HB_EXPORT HB_FHANDLE hb_setGetAltHan( void ); extern HB_EXPORT HB_FHANDLE hb_setGetExtraHan( void ); extern HB_EXPORT HB_FHANDLE hb_setGetPrintHan( void ); +extern HB_EXPORT HB_FHANDLE hb_setGetPrinterHandle( int ); extern HB_EXPORT BOOL hb_setGetAlternate( void ); extern HB_EXPORT char * hb_setGetAltFile( void ); extern HB_EXPORT BOOL hb_setGetAutOpen( void ); diff --git a/harbour/source/rtl/console.c b/harbour/source/rtl/console.c index f0dd13d599..408d8d4257 100644 --- a/harbour/source/rtl/console.c +++ b/harbour/source/rtl/console.c @@ -226,27 +226,29 @@ void hb_conOutErr( const char * pStr, ULONG ulLen ) /* Output an item to the screen and/or printer and/or alternate */ void hb_conOutAlt( const char * pStr, ULONG ulLen ) { + HB_FHANDLE hFile; + HB_TRACE(HB_TR_DEBUG, ("hb_conOutAlt(%s, %lu)", pStr, ulLen)); if( hb_setGetConsole() ) hb_gtWriteCon( ( BYTE * ) pStr, ulLen ); - if( hb_setGetAlternate() && hb_setGetAltHan() != FS_ERROR ) + if( hb_setGetAlternate() && ( hFile = hb_setGetAltHan() ) != FS_ERROR ) { /* Print to alternate file if SET ALTERNATE ON and valid alternate file */ - hb_fsWriteLarge( hb_setGetAltHan(), ( BYTE * ) pStr, ulLen ); + hb_fsWriteLarge( hFile, ( BYTE * ) pStr, ulLen ); } - if( hb_setGetExtraHan() != FS_ERROR ) + if( ( hFile = hb_setGetExtraHan() ) != FS_ERROR ) { /* Print to extra file if valid alternate file */ - hb_fsWriteLarge( hb_setGetExtraHan(), ( BYTE * ) pStr, ulLen ); + hb_fsWriteLarge( hFile, ( BYTE * ) pStr, ulLen ); } - if( hb_setGetPrinter() && hb_setGetPrintHan() != FS_ERROR ) + if( ( hFile = hb_setGetPrinterHandle( HB_SET_PRN_CON ) ) != FS_ERROR ) { /* Print to printer if SET PRINTER ON and valid printer file */ - hb_fsWriteLarge( hb_setGetPrintHan(), ( BYTE * ) pStr, ulLen ); + hb_fsWriteLarge( hFile, ( BYTE * ) pStr, ulLen ); hb_prnPos()->col += ( USHORT ) ulLen; } } @@ -254,13 +256,14 @@ void hb_conOutAlt( const char * pStr, ULONG ulLen ) /* Output an item to the screen and/or printer */ static void hb_conOutDev( const char * pStr, ULONG ulLen ) { + HB_FHANDLE hFile; + HB_TRACE(HB_TR_DEBUG, ("hb_conOutDev(%s, %lu)", pStr, ulLen)); - if( hb_setGetPrintHan() != FS_ERROR && - hb_stricmp( hb_setGetDevice(), "PRINTER" ) == 0 ) + if( ( hFile = hb_setGetPrinterHandle( HB_SET_PRN_DEV ) ) != FS_ERROR ) { /* Display to printer if SET DEVICE TO PRINTER and valid printer file */ - hb_fsWriteLarge( hb_setGetPrintHan(), ( BYTE * ) pStr, ulLen ); + hb_fsWriteLarge( hFile, ( BYTE * ) pStr, ulLen ); hb_prnPos()->col += ( USHORT ) ulLen; } else @@ -343,9 +346,11 @@ HB_FUNC( QQOUT ) /* writes a list of values to the current device (screen or pri HB_FUNC( QOUT ) { + HB_FHANDLE hFile; + hb_conOutAlt( s_szCrLf, s_iCrLfLen ); - if( hb_setGetPrinter() && hb_setGetPrintHan() != FS_ERROR ) + if( ( hFile = hb_setGetPrinterHandle( HB_SET_PRN_CON ) ) != FS_ERROR ) { BYTE buf[ 256 ]; PHB_PRNPOS pPrnPos = hb_prnPos(); @@ -359,13 +364,13 @@ HB_FUNC( QOUT ) { BYTE * pBuf = ( BYTE * ) hb_xgrab( pPrnPos->col ); memset( pBuf, ' ', pPrnPos->col ); - hb_fsWrite( hb_setGetPrintHan(), pBuf, pPrnPos->col ); + hb_fsWrite( hFile, pBuf, pPrnPos->col ); hb_xfree( pBuf ); } else { memset( buf, ' ', pPrnPos->col ); - hb_fsWrite( hb_setGetPrintHan(), buf, pPrnPos->col ); + hb_fsWrite( hFile, buf, pPrnPos->col ); } } } @@ -376,11 +381,12 @@ HB_FUNC( QOUT ) HB_FUNC( __EJECT ) /* Ejects the current page from the printer */ { PHB_PRNPOS pPrnPos; + HB_FHANDLE hFile; - if( hb_setGetPrintHan() != FS_ERROR ) + if( ( hFile = hb_setGetPrinterHandle( HB_SET_PRN_ANY ) ) != FS_ERROR ) { static const BYTE s_byEop[ 4 ] = { 0x0C, 0x0D, 0x00, 0x00 }; /* Buffer is 4 bytes to make CodeGuard happy */ - hb_fsWrite( hb_setGetPrintHan(), s_byEop, 2 ); + hb_fsWrite( hFile, s_byEop, 2 ); } pPrnPos = hb_prnPos(); @@ -399,13 +405,14 @@ HB_FUNC( PCOL ) /* Returns the current printer row position */ static void hb_conDevPos( SHORT iRow, SHORT iCol ) { + HB_FHANDLE hFile; + HB_TRACE(HB_TR_DEBUG, ("hb_conDevPos(%hd, %hd)", iRow, iCol)); /* Position printer if SET DEVICE TO PRINTER and valid printer file otherwise position console */ - if( hb_setGetPrintHan() != FS_ERROR && - hb_stricmp( hb_setGetDevice(), "PRINTER" ) == 0 ) + if( ( hFile = hb_setGetPrinterHandle( HB_SET_PRN_DEV ) ) != FS_ERROR ) { USHORT uiPRow = ( USHORT ) iRow; USHORT uiPCol = ( USHORT ) iCol + ( USHORT ) hb_setGetMargin(); @@ -434,7 +441,7 @@ static void hb_conDevPos( SHORT iRow, SHORT iCol ) { if( iPtr + s_iCrLfLen > ( int ) sizeof( buf ) ) { - hb_fsWrite( hb_setGetPrintHan(), buf, ( USHORT ) iPtr ); + hb_fsWrite( hFile, buf, ( USHORT ) iPtr ); iPtr = 0; } memcpy( &buf[ iPtr ], s_szCrLf, s_iCrLfLen ); @@ -453,7 +460,7 @@ static void hb_conDevPos( SHORT iRow, SHORT iCol ) { if( iPtr == ( int ) sizeof( buf ) ) { - hb_fsWrite( hb_setGetPrintHan(), buf, ( USHORT ) iPtr ); + hb_fsWrite( hFile, buf, ( USHORT ) iPtr ); iPtr = 0; } buf[ iPtr++ ] = ' '; @@ -461,7 +468,7 @@ static void hb_conDevPos( SHORT iRow, SHORT iCol ) } if( iPtr ) - hb_fsWrite( hb_setGetPrintHan(), buf, ( SHORT ) iPtr ); + hb_fsWrite( hFile, buf, ( SHORT ) iPtr ); } } else diff --git a/harbour/source/rtl/filebuf.c b/harbour/source/rtl/filebuf.c index 1ecf81096e..ef5f902ec7 100644 --- a/harbour/source/rtl/filebuf.c +++ b/harbour/source/rtl/filebuf.c @@ -83,6 +83,7 @@ typedef struct _HB_FILE ULONG inode; int used; BOOL shared; + BOOL readonly; HB_FHANDLE hFile; PHB_FLOCK pLocks; UINT uiLocks; @@ -128,7 +129,7 @@ static PHB_FILE hb_fileFind( ULONG device, ULONG inode ) return NULL; } -static PHB_FILE hb_fileNew( HB_FHANDLE hFile, BOOL fShared, +static PHB_FILE hb_fileNew( HB_FHANDLE hFile, BOOL fShared, BOOL fReadonly, ULONG device, ULONG inode, BOOL fBind ) { PHB_FILE pFile = hb_fileFind( device, inode ); @@ -137,10 +138,11 @@ static PHB_FILE hb_fileNew( HB_FHANDLE hFile, BOOL fShared, { pFile = ( PHB_FILE ) hb_xgrab( sizeof( HB_FILE ) ); memset( pFile, 0, sizeof( HB_FILE ) ); - pFile->device = device; - pFile->inode = inode; - pFile->hFile = hFile; - pFile->shared = fShared; + pFile->device = device; + pFile->inode = inode; + pFile->hFile = hFile; + pFile->shared = fShared; + pFile->readonly = fReadonly; if( fBind ) { @@ -310,11 +312,12 @@ PHB_FILE hb_fileExtOpen( BYTE * pFilename, BYTE * pDefExt, struct stat statbuf; BOOL fResult; #endif - BOOL fShared; + BOOL fShared, fReadonly; HB_FHANDLE hFile; BYTE * pszFile; fShared = ( uiExFlags & ( FO_DENYREAD | FO_DENYWRITE | FO_EXCLUSIVE ) ) == 0; + fReadonly = ( uiExFlags & ( FO_READ | FO_WRITE | FO_READWRITE ) ) == FO_READ; pszFile = hb_fsExtName( pFilename, pDefExt, uiExFlags, pPaths ); #if defined( HB_OS_UNIX ) @@ -325,12 +328,12 @@ PHB_FILE hb_fileExtOpen( BYTE * pFilename, BYTE * pDefExt, if( fResult ) { - hb_threadEnterCriticalSection( &s_fileMtx ); pFile = hb_fileFind( statbuf.st_dev, statbuf.st_ino ); if( pFile ) { - if( !fShared || ! pFile->shared || ( uiExFlags & FXO_TRUNCATE ) != 0 ) + if( !fShared || ! pFile->shared || ( uiExFlags & FXO_TRUNCATE ) != 0 || + ( !fReadonly && pFile->readonly ) ) fResult = FALSE; else pFile->used++; @@ -372,16 +375,17 @@ PHB_FILE hb_fileExtOpen( BYTE * pFilename, BYTE * pDefExt, device = ( ULONG ) statbuf.st_dev; inode = ( ULONG ) statbuf.st_ino; } - hb_fsSetIOError( fResult, 0 ); hb_vmLock(); #endif hb_threadEnterCriticalSection( &s_fileMtx ); - pFile = hb_fileNew( hFile, fShared, device, inode, TRUE ); + pFile = hb_fileNew( hFile, fShared, fReadonly, device, inode, TRUE ); hb_threadLeaveCriticalSection( &s_fileMtx ); - if( pFile->hFile != hFile ) + if( !pFile || pFile->hFile != hFile ) hb_fsClose( hFile ); + if( !pFile ) + hb_fsSetError( 32 ); } } hb_xfree( pszFile ); @@ -496,7 +500,7 @@ PHB_FILE hb_fileCreateTemp( const BYTE * pszDir, const BYTE * pszPrefix, hFile = hb_fsCreateTemp( pszDir, pszPrefix, ulAttr, pszName ); if( hFile != FS_ERROR ) - pFile = hb_fileNew( hFile, FALSE, 0, 0, FALSE ); + pFile = hb_fileNew( hFile, FALSE, FALSE, 0, 0, FALSE ); return pFile; } @@ -512,7 +516,7 @@ PHB_FILE hb_fileCreateTempEx( BYTE * pszName, hFile = hb_fsCreateTempEx( pszName, pszDir, pszPrefix, pszExt, ulAttr ); if( hFile != FS_ERROR ) - pFile = hb_fileNew( hFile, FALSE, 0, 0, FALSE ); + pFile = hb_fileNew( hFile, FALSE, FALSE, 0, 0, FALSE ); return pFile; } diff --git a/harbour/source/rtl/hbffind.c b/harbour/source/rtl/hbffind.c index 5927edbf2f..e65381f940 100644 --- a/harbour/source/rtl/hbffind.c +++ b/harbour/source/rtl/hbffind.c @@ -570,11 +570,11 @@ static BOOL hb_fsFindNextLow( PHB_FFIND ffind ) #if defined(__XCC__) || (defined(__POCC__) && __POCC__ >= 500) /* NOTE: PellesC 5.00.1 will go into an infinite loop if we don't split this into two operations. [vszakats] */ - ffind->size = ( HB_FOFFSET ) info->pFindFileData.nFileSizeLow; + ffind->size = ( HB_FOFFSET ) info->pFindFileData.nFileSizeLow; ffind->size += ( HB_FOFFSET ) info->pFindFileData.nFileSizeHigh << 32; #else ffind->size = ( HB_FOFFSET ) info->pFindFileData.nFileSizeLow + - ( ( HB_FOFFSET ) info->pFindFileData.nFileSizeHigh << 32 ); + ( ( HB_FOFFSET ) info->pFindFileData.nFileSizeHigh << 32 ); #endif } @@ -609,34 +609,27 @@ static BOOL hb_fsFindNextLow( PHB_FFIND ffind ) PHB_FFIND_INFO info = ( PHB_FFIND_INFO ) ffind->info; char dirname[ HB_PATH_MAX ]; - char string[ HB_PATH_MAX ]; bFound = FALSE; /* TODO: HB_FA_LABEL handling */ - string[ 0 ] = '\0'; if( ffind->bFirst ) { char * pos; ffind->bFirst = FALSE; - dirname[ 0 ] = '\0'; - info->pattern[ 0 ] = '\0'; - - /* hb_strncpy( string, pszFileName, sizeof( string ) - 1 ); */ - hb_strncpy( string, ffind->pszFileMask, sizeof( string ) - 1 ); - pos = strrchr( string, HB_OS_PATH_DELIM_CHR ); + hb_strncpy( dirname, ffind->pszFileMask, sizeof( dirname ) - 1 ); + pos = strrchr( dirname, HB_OS_PATH_DELIM_CHR ); if( pos ) { hb_strncpy( info->pattern, pos + 1, sizeof( info->pattern ) - 1 ); *( pos + 1 ) = '\0'; - hb_strncpy( dirname, string, sizeof( dirname ) - 1 ); } else { - hb_strncpy( info->pattern, string, sizeof( info->pattern ) - 1 ); + hb_strncpy( info->pattern, dirname, sizeof( info->pattern ) - 1 ); dirname[ 0 ] = '.'; dirname[ 1 ] = HB_OS_PATH_DELIM_CHR; dirname[ 2 ] = '\0'; @@ -652,8 +645,7 @@ static BOOL hb_fsFindNextLow( PHB_FFIND ffind ) { while( ( info->entry = readdir( info->dir ) ) != NULL ) { - hb_strncpy( string, info->entry->d_name, sizeof( string ) - 1 ); - if( hb_strMatchFile( string, info->pattern ) ) + if( hb_strMatchFile( info->entry->d_name, info->pattern ) ) { bFound = TRUE; break; diff --git a/harbour/source/vm/set.c b/harbour/source/vm/set.c index c914da838d..d3a3a9d697 100644 --- a/harbour/source/vm/set.c +++ b/harbour/source/vm/set.c @@ -117,22 +117,25 @@ static BOOL set_logical( PHB_ITEM pItem, BOOL bDefault ) HB_TRACE(HB_TR_DEBUG, ("set_logical(%p)", pItem)); - if( HB_IS_LOGICAL( pItem ) ) - bLogical = hb_itemGetL( pItem ); - else if( HB_IS_STRING( pItem ) ) + if( pItem ) { - char * szString = hb_itemGetCPtr( pItem ); - ULONG ulLen = hb_itemGetCLen( pItem ); + if( HB_IS_LOGICAL( pItem ) ) + bLogical = hb_itemGetL( pItem ); + else if( HB_IS_STRING( pItem ) ) + { + char * szString = hb_itemGetCPtr( pItem ); + ULONG ulLen = hb_itemGetCLen( pItem ); - if( ulLen >= 2 - && ( ( UCHAR ) szString[ 0 ] == 'O' || ( UCHAR ) szString[ 0 ] == 'o' ) - && ( ( UCHAR ) szString[ 1 ] == 'N' || ( UCHAR ) szString[ 1 ] == 'n' ) ) - bLogical = TRUE; - else if( ulLen >= 3 - && ( ( UCHAR ) szString[ 0 ] == 'O' || ( UCHAR ) szString[ 0 ] == 'o' ) - && ( ( UCHAR ) szString[ 1 ] == 'F' || ( UCHAR ) szString[ 1 ] == 'f' ) - && ( ( UCHAR ) szString[ 2 ] == 'F' || ( UCHAR ) szString[ 2 ] == 'f' ) ) - bLogical = FALSE; + if( ulLen >= 2 + && ( ( UCHAR ) szString[ 0 ] == 'O' || ( UCHAR ) szString[ 0 ] == 'o' ) + && ( ( UCHAR ) szString[ 1 ] == 'N' || ( UCHAR ) szString[ 1 ] == 'n' ) ) + bLogical = TRUE; + else if( ulLen >= 3 + && ( ( UCHAR ) szString[ 0 ] == 'O' || ( UCHAR ) szString[ 0 ] == 'o' ) + && ( ( UCHAR ) szString[ 1 ] == 'F' || ( UCHAR ) szString[ 1 ] == 'f' ) + && ( ( UCHAR ) szString[ 2 ] == 'F' || ( UCHAR ) szString[ 2 ] == 'f' ) ) + bLogical = FALSE; + } } return bLogical; @@ -164,29 +167,33 @@ static char * set_string( PHB_ITEM pItem, char * szOldString ) return szString; } -static void close_binary( HB_FHANDLE handle ) +static void close_handle( PHB_SET_STRUCT pSet, HB_set_enum set_specifier ) { - HB_TRACE(HB_TR_DEBUG, ("close_binary(%p)", ( void * ) ( HB_PTRDIFF ) handle)); + HB_FHANDLE * handle_ptr; - if( handle != FS_ERROR ) + HB_TRACE(HB_TR_DEBUG, ("close_handle(%p,%d)", pSet, ( int ) set_specifier)); + + switch( set_specifier ) { - /* Close the file handle without disrupting the current - user file error value */ - hb_fsClose( handle ); + case HB_SET_ALTFILE: + handle_ptr = &pSet->hb_set_althan; + break; + case HB_SET_PRINTFILE: + handle_ptr = &pSet->hb_set_printhan; + break; + case HB_SET_EXTRAFILE: + handle_ptr = &pSet->hb_set_extrahan; + break; + default: + return; } -} -static void close_text( PHB_SET_STRUCT pSet, HB_FHANDLE handle ) -{ - HB_TRACE(HB_TR_DEBUG, ("close_text(%p,%p)", pSet, ( void * ) ( HB_PTRDIFF ) handle)); - - if( handle != FS_ERROR ) + if( *handle_ptr != FS_ERROR ) { - /* Close the file handle without disrupting the current - user file error value */ - if( pSet->HB_SET_EOF ) - hb_fsWrite( handle, ( BYTE * ) "\x1A", 1 ); - hb_fsClose( handle ); + if( set_specifier != HB_SET_PRINTFILE && pSet->HB_SET_EOF ) + hb_fsWrite( *handle_ptr, ( BYTE * ) "\x1A", 1 ); + hb_fsClose( *handle_ptr ); + *handle_ptr = FS_ERROR; } } @@ -224,45 +231,90 @@ static BOOL is_devicename( const char * szFileName ) return FALSE; } -static HB_FHANDLE open_handle( PHB_SET_STRUCT pSet, const char * file_name, BOOL bAppend, const char * def_ext, HB_set_enum set_specifier ) +static void open_handle( PHB_SET_STRUCT pSet, const char * file_name, + BOOL bAppend, HB_set_enum set_specifier ) { PHB_ITEM pError = NULL; - HB_FHANDLE handle; - char path[ HB_PATH_MAX ]; + HB_FHANDLE handle, * handle_ptr; + USHORT uiError; + char * szFileName = NULL, ** set_value; + const char * def_ext; BOOL bPipe = FALSE; - HB_TRACE(HB_TR_DEBUG, ("open_handle(%p, %s, %d, %s, %d)", pSet, file_name, (int) bAppend, def_ext, (int) set_specifier)); - /* Create full filename */ + HB_TRACE(HB_TR_DEBUG, ("open_handle(%p, %s, %d, %d)", pSet, file_name, (int) bAppend, (int) set_specifier)); + + switch( set_specifier ) + { + case HB_SET_ALTFILE: + uiError = 2013; + set_value = &pSet->HB_SET_ALTFILE; + handle_ptr = &pSet->hb_set_althan; + def_ext = ".txt"; + break; + case HB_SET_PRINTFILE: + uiError = 2014; + set_value = &pSet->HB_SET_PRINTFILE; + handle_ptr = &pSet->hb_set_printhan; + def_ext = ".prn"; + break; + case HB_SET_EXTRAFILE: + uiError = 2015; + set_value = &pSet->HB_SET_EXTRAFILE; + handle_ptr = &pSet->hb_set_extrahan; + def_ext = ".prn"; + break; + default: + return; + } + + close_handle( pSet, set_specifier ); + + if( file_name && file_name[ 0 ] != '\0' ) + { + /* Create full filename */ #if defined(HB_OS_UNIX_COMPATIBLE) - bPipe = set_specifier == HB_SET_PRINTFILE && file_name[ 0 ] == '|'; - if( bPipe ) - { - file_name++; - bAppend = FALSE; - } -#endif - if( ! bPipe ) - { - PHB_FNAME pFilename = hb_fsFNameSplit( file_name ); - - if( is_devicename( file_name ) ) + bPipe = file_name[ 0 ] == '|'; + if( bPipe ) { + szFileName = hb_strdup( file_name ); + bAppend = FALSE; + } +#endif + if( ! bPipe ) + { + char path[ HB_PATH_MAX ]; + PHB_FNAME pFilename = hb_fsFNameSplit( file_name ); + + if( is_devicename( file_name ) ) + { #if defined(HB_OS_OS2) || defined(HB_OS_WIN) || defined(HB_OS_DOS) - hb_strupr( ( char * ) pFilename->szName ); + hb_strupr( ( char * ) pFilename->szName ); #endif - } - else - { - if( pFilename->szExtension == NULL && def_ext && pSet->HB_SET_DEFEXTENSIONS ) - pFilename->szExtension = def_ext; + } + else + { + if( pFilename->szExtension == NULL && def_ext && pSet->HB_SET_DEFEXTENSIONS ) + pFilename->szExtension = def_ext; - if( pFilename->szPath == NULL && pSet->HB_SET_DEFAULT ) - pFilename->szPath = pSet->HB_SET_DEFAULT; + if( pFilename->szPath == NULL && pSet->HB_SET_DEFAULT ) + pFilename->szPath = pSet->HB_SET_DEFAULT; + } + hb_fsFNameMerge( path, pFilename ); + hb_xfree( pFilename ); + szFileName = hb_strdup( path ); } - hb_fsFNameMerge( path, pFilename ); - hb_xfree( pFilename ); } + /* free the old value before setting the new one (CA-Cl*pper does it. + * This code must be executed after setting szFileName, [druzus] + */ + if( *set_value ) + hb_xfree( *set_value ); + *set_value = NULL; + + if( !szFileName ) + return; + /* Open the file either in append (bAppend) or truncate mode (!bAppend), but always use binary mode */ @@ -271,18 +323,18 @@ static HB_FHANDLE open_handle( PHB_SET_STRUCT pSet, const char * file_name, BOOL handle = FS_ERROR; while( handle == FS_ERROR ) { - BOOL bCreate = FALSE; - if( bPipe ) - handle = hb_fsPOpen( ( BYTE * ) file_name, ( BYTE * ) "w" ); + handle = hb_fsPOpen( ( BYTE * ) szFileName + 1, ( BYTE * ) "w" ); else { + BOOL bCreate = FALSE; + if( bAppend ) { /* Append mode */ - if( hb_fsFileExists( path ) ) + if( hb_fsFileExists( szFileName ) ) { /* If the file already exists, open it (in read-write mode, in case of non-Unix and text modes). */ - handle = hb_fsOpen( ( BYTE * ) path, FO_READWRITE | FO_DENYWRITE ); + handle = hb_fsOpen( ( BYTE * ) szFileName, FO_READWRITE | FO_DENYWRITE ); if( handle != FS_ERROR ) { /* Position to EOF */ /* Special binary vs. text file handling - even for UN*X, now @@ -312,20 +364,12 @@ static HB_FHANDLE open_handle( PHB_SET_STRUCT pSet, const char * file_name, BOOL bCreate = TRUE; /* Always create a new file for overwrite mode. */ if( bCreate ) - handle = hb_fsCreate( ( BYTE * ) path, FC_NORMAL ); + handle = hb_fsCreate( ( BYTE * ) szFileName, FC_NORMAL ); } if( handle == FS_ERROR ) { - if( set_specifier == HB_SET_ALTFILE ) - pError = hb_errRT_FileError( pError, HB_ERR_SS_TERMINAL, EG_CREATE, 2013, path ); - else if( set_specifier == HB_SET_PRINTFILE ) - pError = hb_errRT_FileError( pError, HB_ERR_SS_TERMINAL, EG_CREATE, 2014, path ); - else if( set_specifier == HB_SET_EXTRAFILE ) - pError = hb_errRT_FileError( pError, HB_ERR_SS_TERMINAL, EG_CREATE, 2015, path ); - else - break; - + pError = hb_errRT_FileError( pError, HB_ERR_SS_TERMINAL, EG_CREATE, uiError, szFileName ); if( hb_errLaunch( pError ) != E_RETRY ) break; } @@ -334,7 +378,22 @@ static HB_FHANDLE open_handle( PHB_SET_STRUCT pSet, const char * file_name, BOOL if( pError ) hb_itemRelease( pError ); - return handle; + if( handle == FS_ERROR ) + { + hb_xfree( szFileName ); + szFileName = NULL; + } + + /* user RT error handler can open it too so we have to + * close it again if necessary + */ + close_handle( pSet, set_specifier ); + * handle_ptr = handle; + if( *set_value ) + hb_xfree( *set_value ); + *set_value = szFileName; + + return; } static void hb_set_OSCODEPAGE( PHB_SET_STRUCT pSet ) @@ -467,19 +526,17 @@ HB_FUNC( SETCANCEL ) hb_setSetItem( HB_SET_CANCEL, hb_param( 1, HB_IT_LOGICAL ) ); } -static void hb_set_PRINTFILE_default( PHB_SET_STRUCT pSet ) +/* return default printer device */ +static char * hb_set_PRINTFILE_default( void ) { - if( pSet->HB_SET_PRINTFILE ) - hb_xfree( pSet->HB_SET_PRINTFILE ); - #if defined(HB_OS_UNIX) - pSet->HB_SET_PRINTFILE = hb_strdup( "|lpr" ); + return hb_strdup( "|lpr" ); #elif defined(HB_OS_DOS) - pSet->HB_SET_PRINTFILE = hb_strdup( "PRN" ); + return hb_strdup( "PRN" ); #elif defined(HB_OS_WIN) || defined(HB_OS_OS2) - pSet->HB_SET_PRINTFILE = hb_strdup( "LPT1" ); + return hb_strdup( "LPT1" ); #else - pSet->HB_SET_PRINTFILE = hb_strdup( "PRN" ); /* TOFIX */ + return hb_strdup( "PRN" ); /* TOFIX */ #endif } @@ -488,8 +545,6 @@ HB_FUNC( SET ) HB_STACK_TLS_PRELOAD PHB_SET_STRUCT pSet = hb_stackSetStruct(); int args = hb_pcount(); - BOOL bFlag; - HB_set_enum set_specifier = ( args > 0 ) ? ( HB_set_enum ) hb_parni( 1 ) : HB_SET_INVALID_; PHB_ITEM pArg2 = ( args > 1 ) ? hb_param( 2, HB_IT_ANY ) : NULL; PHB_ITEM pArg3 = ( args > 2 ) ? hb_param( 3, HB_IT_ANY ) : NULL; @@ -506,32 +561,8 @@ HB_FUNC( SET ) break; case HB_SET_ALTFILE: hb_retc( pSet->HB_SET_ALTFILE ); - if( args > 1 ) - { - if( HB_IS_NIL( pArg2 ) ) - { - if( pSet->HB_SET_ALTFILE ) - { - hb_xfree( pSet->HB_SET_ALTFILE ); - pSet->HB_SET_ALTFILE = NULL; - } - } - else - { - pSet->HB_SET_ALTFILE = set_string( pArg2, pSet->HB_SET_ALTFILE ); - } - } - if( args > 2 ) - bFlag = set_logical( pArg3, FALSE ); - else - bFlag = FALSE; - if( args > 1 ) - { - close_text( pSet, pSet->hb_set_althan ); - pSet->hb_set_althan = FS_ERROR; - if( pSet->HB_SET_ALTFILE && pSet->HB_SET_ALTFILE[ 0 ] != '\0' ) - pSet->hb_set_althan = open_handle( pSet, pSet->HB_SET_ALTFILE, bFlag, ".txt", HB_SET_ALTFILE ); - } + if( pArg2 && HB_IS_STRING( pArg2 ) ) + open_handle( pSet, hb_itemGetCPtr( pArg2 ), set_logical( pArg3, FALSE ), HB_SET_ALTFILE ); break; case HB_SET_AUTOPEN: hb_retl( pSet->HB_SET_AUTOPEN ); @@ -650,13 +681,11 @@ HB_FUNC( SET ) break; case HB_SET_DEVICE: hb_retc( pSet->HB_SET_DEVICE ); - if( args > 1 && ! HB_IS_NIL( pArg2 ) ) + if( pArg2 && HB_IS_STRING( pArg2 ) ) { /* If the print file is not already open, open it in overwrite mode. */ pSet->HB_SET_DEVICE = set_string( pArg2, pSet->HB_SET_DEVICE ); - if( hb_stricmp( pSet->HB_SET_DEVICE, "PRINTER" ) == 0 && pSet->hb_set_printhan == FS_ERROR && - pSet->HB_SET_PRINTFILE && pSet->HB_SET_PRINTFILE[ 0 ] != '\0' ) - pSet->hb_set_printhan = open_handle( pSet, pSet->HB_SET_PRINTFILE, FALSE, ".prn", HB_SET_PRINTFILE ); + pSet->hb_set_prndevice = hb_stricmp( pSet->HB_SET_DEVICE, "PRINTER" ) == 0; } break; case HB_SET_EOF: @@ -712,32 +741,8 @@ HB_FUNC( SET ) break; case HB_SET_EXTRAFILE: hb_retc( pSet->HB_SET_EXTRAFILE ); - if( args > 1 ) - { - if( HB_IS_NIL( pArg2 ) ) - { - if( pSet->HB_SET_EXTRAFILE ) - { - hb_xfree( pSet->HB_SET_EXTRAFILE ); - pSet->HB_SET_EXTRAFILE = NULL; - } - } - else - { - pSet->HB_SET_EXTRAFILE = set_string( pArg2, pSet->HB_SET_EXTRAFILE ); - } - } - if( args > 2 ) - bFlag = set_logical( pArg3, FALSE ); - else - bFlag = FALSE; - if( args > 1 && ! HB_IS_NIL( pArg2 ) ) - { - close_text( pSet, pSet->hb_set_extrahan ); - pSet->hb_set_extrahan = FS_ERROR; - if( pSet->HB_SET_EXTRAFILE && pSet->HB_SET_EXTRAFILE[ 0 ] != '\0' ) - pSet->hb_set_extrahan = open_handle( pSet, pSet->HB_SET_EXTRAFILE, bFlag, ".prn", HB_SET_EXTRAFILE ); - } + if( pArg2 && HB_IS_STRING( pArg2 ) ) + open_handle( pSet, hb_itemGetCPtr( pArg2 ), set_logical( pArg3, FALSE ), HB_SET_EXTRAFILE ); break; case HB_SET_FIXED: hb_retl( pSet->HB_SET_FIXED ); @@ -831,24 +836,12 @@ HB_FUNC( SET ) break; case HB_SET_PRINTFILE: hb_retc( pSet->HB_SET_PRINTFILE ); - if( args > 1 && ! HB_IS_NIL( pArg2 ) ) + if( pArg2 && HB_IS_STRING( pArg2 ) ) { + open_handle( pSet, hb_itemGetCPtr( pArg2 ), set_logical( pArg3, FALSE ), HB_SET_PRINTFILE ); /* With SET PRINTER TO or Set( _SET_PRINTFILE, "" ) are expected to activate the default printer [jarabal] */ - if( hb_itemGetCLen( pArg2 ) == 0 ) - hb_set_PRINTFILE_default( pSet ); - else - pSet->HB_SET_PRINTFILE = set_string( pArg2, pSet->HB_SET_PRINTFILE ); - } - if( args > 2 ) - bFlag = set_logical( pArg3, FALSE ); - else - bFlag = FALSE; - if( args > 1 && ! HB_IS_NIL( pArg2 ) ) - { - close_binary( pSet->hb_set_printhan ); - pSet->hb_set_printhan = FS_ERROR; - if( pSet->HB_SET_PRINTFILE && pSet->HB_SET_PRINTFILE[ 0 ] != '\0' ) - pSet->hb_set_printhan = open_handle( pSet, pSet->HB_SET_PRINTFILE, bFlag, ".prn", HB_SET_PRINTFILE ); + if( pSet->HB_SET_PRINTFILE == NULL ) + pSet->HB_SET_PRINTFILE = hb_set_PRINTFILE_default(); } break; case HB_SET_SCOREBOARD: @@ -1060,6 +1053,7 @@ void hb_setInitialize( PHB_SET_STRUCT pSet ) pSet->HB_SET_BELL = FALSE; pSet->HB_SET_CANCEL = TRUE; pSet->hb_set_century = FALSE; + pSet->hb_set_prndevice = FALSE; pSet->HB_SET_COLOR = ( char * ) hb_xgrab( HB_CLRSTR_LEN + 1 ); hb_strncpy( pSet->HB_SET_COLOR, "W/N,N/W,N/N,N/N,N/W", HB_CLRSTR_LEN ); pSet->HB_SET_CONFIRM = FALSE; @@ -1117,9 +1111,7 @@ void hb_setInitialize( PHB_SET_STRUCT pSet ) pSet->HB_SET_PATH = hb_strdup( "" ); pSet->hb_set_path = NULL; pSet->HB_SET_PRINTER = FALSE; - /* Default printer device */ - pSet->HB_SET_PRINTFILE = NULL; - hb_set_PRINTFILE_default( pSet ); + pSet->HB_SET_PRINTFILE = hb_set_PRINTFILE_default(); pSet->hb_set_printhan = FS_ERROR; pSet->HB_SET_SCOREBOARD = TRUE; pSet->HB_SET_SCROLLBREAK = TRUE; @@ -1151,9 +1143,9 @@ void hb_setRelease( PHB_SET_STRUCT pSet ) { HB_TRACE(HB_TR_DEBUG, ("hb_setRelease()")); - close_text( pSet, pSet->hb_set_althan ); - close_text( pSet, pSet->hb_set_extrahan ); - close_binary( pSet->hb_set_printhan ); + close_handle( pSet, HB_SET_ALTFILE ); + close_handle( pSet, HB_SET_EXTRAFILE ); + close_handle( pSet, HB_SET_PRINTFILE ); if( pSet->HB_SET_ALTFILE ) hb_xfree( pSet->HB_SET_ALTFILE ); if( pSet->HB_SET_DATEFORMAT ) hb_xfree( pSet->HB_SET_DATEFORMAT ); @@ -1292,64 +1284,6 @@ int hb_setListenerRemove( int listener ) return listener; } -static BOOL hb_setSetFile( HB_set_enum set_specifier, const char * szFile, BOOL fAdditive ) -{ - HB_STACK_TLS_PRELOAD - PHB_SET_STRUCT pSet = hb_stackSetStruct(); - BOOL fResult = TRUE; - - switch( set_specifier ) - { - case HB_SET_ALTFILE: - if( pSet->HB_SET_ALTFILE ) - hb_xfree( pSet->HB_SET_ALTFILE ); - /* Limit size of SET strings to 64K, truncating if source is longer */ - pSet->HB_SET_ALTFILE = szFile ? hb_strndup( szFile, USHRT_MAX ) : NULL; - close_text( pSet, pSet->hb_set_althan ); - pSet->hb_set_althan = FS_ERROR; - if( pSet->HB_SET_ALTFILE && pSet->HB_SET_ALTFILE[ 0 ] != '\0' ) - pSet->hb_set_althan = open_handle( pSet, pSet->HB_SET_ALTFILE, - fAdditive, ".txt", HB_SET_ALTFILE ); - break; - - case HB_SET_EXTRAFILE: - if( pSet->HB_SET_EXTRAFILE ) - hb_xfree( pSet->HB_SET_EXTRAFILE ); - /* Limit size of SET strings to 64K, truncating if source is longer */ - pSet->HB_SET_EXTRAFILE = szFile ? hb_strndup( szFile, USHRT_MAX ) : NULL; - if( szFile ) - { - close_text( pSet, pSet->hb_set_extrahan ); - pSet->hb_set_extrahan = FS_ERROR; - if( pSet->HB_SET_EXTRAFILE && pSet->HB_SET_EXTRAFILE[ 0 ] != '\0' ) - pSet->hb_set_extrahan = open_handle( pSet, pSet->HB_SET_EXTRAFILE, - fAdditive, ".prn", HB_SET_EXTRAFILE ); - } - break; - - case HB_SET_PRINTFILE: - if( pSet->HB_SET_PRINTFILE ) - hb_xfree( pSet->HB_SET_PRINTFILE ); - /* Limit size of SET strings to 64K, truncating if source is longer */ - pSet->HB_SET_PRINTFILE = szFile ? hb_strndup( szFile, USHRT_MAX ) : NULL; - if( szFile ) - { - close_binary( pSet->hb_set_printhan ); - pSet->hb_set_printhan = FS_ERROR; - if( pSet->HB_SET_PRINTFILE && pSet->HB_SET_PRINTFILE[ 0 ] != '\0' ) - pSet->hb_set_printhan = open_handle( pSet, pSet->HB_SET_PRINTFILE, - fAdditive, ".prn", HB_SET_PRINTFILE ); - } - break; - - default: - fResult = FALSE; - break; - } - - return fResult; -} - BOOL hb_setSetItem( HB_set_enum set_specifier, PHB_ITEM pItem ) { HB_STACK_TLS_PRELOAD @@ -1370,8 +1304,13 @@ BOOL hb_setSetItem( HB_set_enum set_specifier, PHB_ITEM pItem ) /* This sets needs 3-rd parameter to indicate additive mode * so they cannot be fully supported by this function */ - fResult = hb_setSetFile( set_specifier, HB_IS_STRING( pItem ) ? - hb_itemGetCPtr( pItem ) : NULL, FALSE ); + if( HB_IS_STRING( pItem ) || HB_IS_NIL( pItem ) ) + { + open_handle( pSet, hb_itemGetCPtr( pItem ), FALSE, set_specifier ); + fResult = TRUE; + if( set_specifier == HB_SET_PRINTFILE && pSet->HB_SET_PRINTFILE == NULL ) + pSet->HB_SET_PRINTFILE = hb_set_PRINTFILE_default(); + } break; case HB_SET_ALTERNATE: @@ -1823,12 +1762,7 @@ BOOL hb_setSetItem( HB_set_enum set_specifier, PHB_ITEM pItem ) if( pSet->HB_SET_DEVICE ) hb_xfree( pSet->HB_SET_DEVICE ); pSet->HB_SET_DEVICE = szValue; - - /* If the print file is not already open, open it in overwrite mode. */ - if( hb_stricmp( szValue, "PRINTER" ) == 0 && pSet->hb_set_printhan == FS_ERROR && - pSet->HB_SET_PRINTFILE && pSet->HB_SET_PRINTFILE[ 0 ] != '\0' ) - pSet->hb_set_printhan = open_handle( pSet, pSet->HB_SET_PRINTFILE, - FALSE, ".prn", HB_SET_PRINTFILE ); + pSet->hb_set_prndevice = hb_stricmp( szValue, "PRINTER" ) == 0; fResult = TRUE; } break; @@ -1949,11 +1883,21 @@ BOOL hb_setSetItem2( HB_set_enum set_specifier, PHB_ITEM pItem1, PHB_ITEM pItem2 case HB_SET_ALTFILE: case HB_SET_EXTRAFILE: case HB_SET_PRINTFILE: - hb_setListenerNotify( set_specifier, HB_SET_LISTENER_BEFORE ); - fResult = hb_setSetFile( set_specifier, HB_IS_STRING( pItem1 ) ? - hb_itemGetCPtr( pItem1 ) : NULL, - pItem2 && set_logical( pItem2, FALSE ) ); - hb_setListenerNotify( set_specifier, HB_SET_LISTENER_AFTER ); + if( HB_IS_STRING( pItem1 ) || HB_IS_NIL( pItem1 ) ) + { + HB_STACK_TLS_PRELOAD + PHB_SET_STRUCT pSet = hb_stackSetStruct(); + + hb_setListenerNotify( set_specifier, HB_SET_LISTENER_BEFORE ); + + open_handle( pSet, hb_itemGetCPtr( pItem1 ), + set_logical( pItem2, FALSE ), set_specifier ); + fResult = TRUE; + if( set_specifier == HB_SET_PRINTFILE && pSet->HB_SET_PRINTFILE == NULL ) + pSet->HB_SET_PRINTFILE = hb_set_PRINTFILE_default(); + + hb_setListenerNotify( set_specifier, HB_SET_LISTENER_AFTER ); + } break; default: fResult = hb_setSetItem( set_specifier, pItem1 ); @@ -2742,3 +2686,29 @@ UCHAR * hb_osDecode( UCHAR * szFileName, BOOL * pfFree ) return szFileName; } + +HB_FHANDLE hb_setGetPrinterHandle( int iType ) +{ + HB_STACK_TLS_PRELOAD + PHB_SET_STRUCT pSet = hb_stackSetStruct(); + + switch( iType ) + { + case HB_SET_PRN_DEV: + if( !pSet->hb_set_prndevice ) + return FS_ERROR; + break; + case HB_SET_PRN_CON: + if( !pSet->HB_SET_PRINTER ) + return FS_ERROR; + case HB_SET_PRN_ANY: + break; + default: + return FS_ERROR; + } + + if( pSet->hb_set_printhan == FS_ERROR && pSet->HB_SET_PRINTFILE ) + open_handle( pSet, pSet->HB_SET_PRINTFILE, FALSE, HB_SET_PRINTFILE ); + + return pSet->hb_set_printhan; +} diff --git a/harbour/utils/hbmk2/hbmk2.prg b/harbour/utils/hbmk2/hbmk2.prg index b92ca12cf1..a86efd94e6 100644 --- a/harbour/utils/hbmk2/hbmk2.prg +++ b/harbour/utils/hbmk2/hbmk2.prg @@ -4357,7 +4357,9 @@ STATIC FUNCTION FN_Expand( cFileName, lCommandLine ) LOCAL aFileList LOCAL aFile LOCAL aDir +#if defined( __PLATFORM__WINDOWS ) LOCAL cExt +#endif #if defined( __PLATFORM__UNIX ) /* Disable expansion if this came from the command line */ @@ -4374,7 +4376,9 @@ STATIC FUNCTION FN_Expand( cFileName, lCommandLine ) aFileList := {} +#if defined( __PLATFORM__WINDOWS ) cExt := FN_ExtGet( cFileName ) +#endif aDir := Directory( cFileName ) FOR EACH aFile IN aDir #if defined( __PLATFORM__WINDOWS )