diff --git a/harbour/ChangeLog b/harbour/ChangeLog index d40a986658..519ae34aad 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,18 @@ +19990905-17:55 EDT David G. Holm + * source/rtl/console.c + + Added code to preserve the current user file error code when + using Harbour hb_fs... functions. + * source/rtl/set.c + + Added code to preserve the current user file error code when + using Harbour hb_fs... functions. + + Added code to remove the old EOF character ('\x1A') when + appending to text-mode files on non-Unix platforms. + * tests/working/output.prg + * Changed the names of the output files to OUTPUT_A (.txt), + OUTPUT_E.EXT, and OUTPUT_P (.prn) so that the files may be + examined and deleted without having to worry about the .PRG + file (the extensions in parentheses are the default ones). + 19990905-17:48 GMT+1 Victor Szel * source/rtl/dbf1.c % Uses hb_itemPutN?Len() instead of hb_itemSetNLen(), so it's a bit diff --git a/harbour/source/rtl/console.c b/harbour/source/rtl/console.c index 57052121de..d91effe4cb 100644 --- a/harbour/source/rtl/console.c +++ b/harbour/source/rtl/console.c @@ -313,6 +313,7 @@ static void hb_altout( char * pStr, ULONG len ) if( hb_set.HB_SET_ALTERNATE && hb_set_althan >= 0 ) { /* Print to alternate file if SET ALTERNATE ON and valid alternate file */ + int user_ferror = hb_fsError(); /* Save current user file error code */ unsigned write_len; ULONG count = len; pPtr = pStr; @@ -331,10 +332,12 @@ static void hb_altout( char * pStr, ULONG len ) hb_fsWrite( hb_set_althan, ( BYTE * ) pPtr, write_len ); pPtr += write_len; } + hb_fsSetError( user_ferror ); /* Restore last user file error code */ } if( hb_set_extrahan >= 0 ) { /* Print to extra file if valid alternate file */ + int user_ferror = hb_fsError(); /* Save current user file error code */ unsigned write_len; ULONG count = len; pPtr = pStr; @@ -353,10 +356,12 @@ static void hb_altout( char * pStr, ULONG len ) hb_fsWrite( hb_set_extrahan, ( BYTE * ) pPtr, write_len ); pPtr += write_len; } + hb_fsSetError( user_ferror ); /* Restore last user file error code */ } if( hb_set.HB_SET_PRINTER && hb_set_printhan >= 0 ) { /* Print to printer if SET PRINTER ON and valid printer file */ + int user_ferror = hb_fsError(); /* Save current user file error code */ unsigned write_len; ULONG count = len; pPtr = pStr; @@ -377,6 +382,7 @@ static void hb_altout( char * pStr, ULONG len ) } if( len + s_uiPCol > USHRT_MAX ) s_uiPCol = USHRT_MAX; else s_uiPCol += len; + hb_fsSetError( user_ferror ); /* Restore last user file error code */ } } @@ -386,6 +392,7 @@ static void hb_devout( char * pStr, ULONG len ) if( hb_set_printhan >= 0 && hb_stricmp( hb_set.HB_SET_DEVICE, "PRINTER" ) == 0 ) { /* Display to printer if SET DEVICE TO PRINTER and valid printer file */ + int user_ferror = hb_fsError(); /* Save current user file error code */ unsigned write_len; ULONG count = len; char * pPtr = pStr; @@ -406,6 +413,7 @@ static void hb_devout( char * pStr, ULONG len ) } if( len + s_uiPCol > USHRT_MAX ) s_uiPCol = USHRT_MAX; else s_uiPCol += len; + hb_fsSetError( user_ferror ); /* Restore last user file error code */ } else { @@ -472,6 +480,7 @@ void hb_devpos( WORD row, WORD col ) otherwise position console */ if( hb_set_printhan >= 0 && hb_stricmp( hb_set.HB_SET_DEVICE, "PRINTER" ) == 0 ) { + int user_ferror = hb_fsError(); /* Save current user file error code */ if( row < s_uiPRow ) { hb_fsWrite( hb_set_printhan, ( BYTE * ) "\x0C", 1 ); @@ -489,6 +498,7 @@ void hb_devpos( WORD row, WORD col ) s_uiPRow = row; s_uiPCol = col; + hb_fsSetError( user_ferror ); /* Restore last user file error code */ } else { @@ -537,11 +547,13 @@ HARBOUR HB_QOUT( void ) if( hb_set.HB_SET_PRINTER && hb_set_printhan >= 0 ) { + int user_ferror = hb_fsError(); /* Save current user file error code */ s_uiPRow++; s_uiPCol = hb_set.HB_SET_MARGIN; count = s_uiPCol; while( count-- > 0 ) hb_fsWrite( hb_set_printhan, ( BYTE * ) " ", 1 ); + hb_fsSetError( user_ferror ); /* Restore last user file error code */ } HB_QQOUT(); @@ -669,8 +681,10 @@ 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 ) { + int user_ferror = hb_fsError(); /* Save current user file error code */ hb_fsWrite( hb_set_printhan, ( BYTE * ) "\x0C\x0D", 2 ); s_uiPRow = s_uiPCol = 0; + hb_fsSetError( user_ferror ); /* Restore last user file error code */ } } diff --git a/harbour/source/rtl/set.c b/harbour/source/rtl/set.c index c83cedc44a..2aa3f45ce6 100644 --- a/harbour/source/rtl/set.c +++ b/harbour/source/rtl/set.c @@ -29,6 +29,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit their web site at http://www.gnu.org/). + V 1.68 David G. Holm Added user file error code safeguards. + When opening a "text" file is append + mode in open_handle(), remove the EOF + character from the end of the file. + V 1.67 David G. Holm Corrected file open/create logic + in open_handle() function. V 1.64 Victor Szel Converted to use the FS API. hb_err*() handles E_BREAK. extrahan closing mode on exit fixed. @@ -226,22 +232,33 @@ static char * set_string( PHB_ITEM pItem, char * old_str ) static void close_binary( FHANDLE handle ) { if( handle != FS_ERROR ) + { + /* Close the file handle without disrupting the current + user file error value */ + int user_ferror = hb_fsError(); hb_fsClose( handle ); + hb_fsSetError( user_ferror ); + } } static void close_text( FHANDLE handle ) { if( handle != FS_ERROR ) { + /* Close the file handle without disrupting the current + user file error value */ + int user_ferror = hb_fsError(); #if ! defined(OS_UNIX_COMPATIBLE) hb_fsWrite( handle, (BYTE *)"\x1A", 1 ); #endif hb_fsClose( handle ); + hb_fsSetError( user_ferror ); } } static FHANDLE open_handle( char * file_name, BOOL bAppend, char * def_ext, HB_set_enum set_specifier ) { + int user_ferror = hb_fsError(); /* Save the current user file error code */ FHANDLE handle; PHB_FNAME pFilename; char path[ _POSIX_PATH_MAX + 1 ]; @@ -272,10 +289,30 @@ static FHANDLE open_handle( char * file_name, BOOL bAppend, char * def_ext, HB_s if( bAppend ) { /* Append mode */ if( hb_fsFile( (BYTE *)path ) ) - { /* If the file already exists, open it... */ - handle = hb_fsOpen( (BYTE *)path, FO_WRITE | FO_DENYWRITE ); + { /* 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 ); if( handle != FS_ERROR ) - hb_fsSeek( handle, 0, FS_END ); /* ... then go to EOF to append. */ + { /* Position to EOF */ + #if ! defined(HB_OS_UNIX_COMPATIBLE) + /* Non-Unix needs special binary vs. text file handling */ + if( set_specifier == HB_SET_PRINTFILE ) + { /* PRINTFILE is binary and needs no special handling. */ + #endif + hb_fsSeek( handle, 0, FS_END ); + #if ! defined(HB_OS_UNIX_COMPATIBLE) + } + else + { /* All other files are text files and may have an EOF + ('\x1A') character at the end (non-UNIX only). */ + char cEOF = '\0'; + hb_fsSeek( handle, -1, FS_END ); /* Position to last char. */ + hb_fsRead( handle, &cEOF, 1 ); /* Read the last char. */ + if( cEOF == '\x1A' ) /* If it's an EOF, */ + hb_fsSeek( handle, -1, FS_END ); /* Then write over it. */ + } + #endif + } } else bCreate = TRUE; /* Otherwise create a new file. */ } @@ -300,6 +337,7 @@ static FHANDLE open_handle( char * file_name, BOOL bAppend, char * def_ext, HB_s break; } } + hb_fsSetError( user_ferror ); /* Restore the current user file error code */ return handle; } diff --git a/harbour/tests/working/output.prg b/harbour/tests/working/output.prg index 5f8e41eae9..4528352fdb 100644 --- a/harbour/tests/working/output.prg +++ b/harbour/tests/working/output.prg @@ -15,9 +15,9 @@ function Main() OUTSTD (cNewLine, "Testing Harbour device management on", DATE()) - SET ALTERNATE TO OUTPUT ADDITIVE - SET (_SET_EXTRAFILE, "OUTPUT.EXT", .F.) - SET PRINTER TO OUTPUT + SET ALTERNATE TO OUTPUT_A ADDITIVE + SET (_SET_EXTRAFILE, "OUTPUT_E.EXT", .F.) + SET PRINTER TO OUTPUT_P SET MARGIN TO 5 QOUT ("SCREEN, EXTRA, NOT ALTERNATE, NOT PRINTER") @ 5,5 SAY "SCREEN, NOT EXTRA, NOT ALTERNATE NOT PRINTER" @@ -29,7 +29,7 @@ function Main() SET (_SET_EXTRAFILE, "") QOUT ("SCREEN, ALTERNATE AND PRINTER AGAIN, BUT NOT EXTRA") SET PRINTER OFF - SET (_SET_EXTRAFILE, "OUTPUT.EXT", .T.) + SET (_SET_EXTRAFILE, "OUTPUT_E.EXT", .T.) QOUT ("SCREEN, EXTRA, AND ALTERNATE, BUT NOT PRINTER") @ 15,15 SAY "PRINTER, NOT SCREEN, NOT ALTERNATE" EJECT