From 6bfbdc7bd64c55407d09c36a73ea7068b84a2721 Mon Sep 17 00:00:00 2001 From: Przemyslaw Czerpak Date: Sat, 26 Jul 2008 14:26:11 +0000 Subject: [PATCH] 2008-07-26 16:25 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/contrib/hbmzip/zip.c ! fixed access to uninitialized member of z_stream by simple initialization. Anyhow it's minor bug in MINIZIP code exploited HB_ZipDeleteFile() which causes that TEXT flag is not set after raw binary file updating. There is also no API call to make it manually. * harbour/contrib/hbmzip/hbmzip.c * harbour/contrib/hbmzip/readme.txt + added HB_ZipDeleteFile( cZipFile, cFileMask ) --> nError * harbour/common.mak * harbour/source/rtl/Makefile + harbour/source/rtl/dirscan.prg + added HB_DirScan( cPath, cFileMask, cAttr ) * harbour/source/rtl/strmatch.c + added HB_FileMatch( cFile, cPattern ) * harbour/include/hbextern.ch + added HB_DirScan(), HB_FileMatch() * harbour/contrib/xhb/dirrec.prg * changed to use HB_DirScan() --- harbour/ChangeLog | 26 ++++ harbour/common.mak | 1 + harbour/contrib/hbmzip/hbmzip.c | 235 ++++++++++++++++++++++++++++-- harbour/contrib/hbmzip/readme.txt | 7 +- harbour/contrib/hbmzip/zip.c | 1 + harbour/contrib/xhb/dirrec.prg | 44 ++---- harbour/include/hbextern.ch | 4 +- harbour/source/rtl/Makefile | 1 + harbour/source/rtl/dirscan.prg | 96 ++++++++++++ harbour/source/rtl/strmatch.c | 6 + 10 files changed, 374 insertions(+), 47 deletions(-) create mode 100644 harbour/source/rtl/dirscan.prg diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 3ca9970fd6..00cb4dcc74 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,32 @@ 2008-12-31 13:59 UTC+0100 Foo Bar */ +2008-07-26 16:25 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/contrib/hbmzip/zip.c + ! fixed access to uninitialized member of z_stream by simple + initialization. Anyhow it's minor bug in MINIZIP code exploited + HB_ZipDeleteFile() which causes that TEXT flag is not set after + raw binary file updating. There is also no API call to make it + manually. + + * harbour/contrib/hbmzip/hbmzip.c + * harbour/contrib/hbmzip/readme.txt + + added HB_ZipDeleteFile( cZipFile, cFileMask ) --> nError + + * harbour/common.mak + * harbour/source/rtl/Makefile + + harbour/source/rtl/dirscan.prg + + added HB_DirScan( cPath, cFileMask, cAttr ) + + * harbour/source/rtl/strmatch.c + + added HB_FileMatch( cFile, cPattern ) + + * harbour/include/hbextern.ch + + added HB_DirScan(), HB_FileMatch() + + * harbour/contrib/xhb/dirrec.prg + * changed to use HB_DirScan() + 2008-07-26 12:22 UTC+0200 Viktor Szakats (harbour.01 syenar hu) * TODO * Updated. diff --git a/harbour/common.mak b/harbour/common.mak index ddab7253a7..e1af0cdd9f 100644 --- a/harbour/common.mak +++ b/harbour/common.mak @@ -600,6 +600,7 @@ RTL_LIB_OBJS = \ $(OBJ_DIR)\dbedit$(OBJEXT) \ $(OBJ_DIR)\devoutp$(OBJEXT) \ $(OBJ_DIR)\dircmd$(OBJEXT) \ + $(OBJ_DIR)\dirscan$(OBJEXT) \ $(OBJ_DIR)\einstv52$(OBJEXT) \ $(OBJ_DIR)\einstvar$(OBJEXT) \ $(OBJ_DIR)\einstvau$(OBJEXT) \ diff --git a/harbour/contrib/hbmzip/hbmzip.c b/harbour/contrib/hbmzip/hbmzip.c index 4e62e93e1f..c373ac067e 100644 --- a/harbour/contrib/hbmzip/hbmzip.c +++ b/harbour/contrib/hbmzip/hbmzip.c @@ -80,6 +80,7 @@ #endif #endif +#define HB_Z_IOBUF_SIZE ( 1024 * 16 ) static HB_GARBAGE_FUNC( hb_zipfile_destructor ) { @@ -133,7 +134,7 @@ static gzFile hb_unzipfileParam( int iParam ) /* HB_ZipOpen( cFileName, [ iMode = HB_ZIP_CREATE ], [ @cGlobalComment ] ) --> hZip */ HB_FUNC( HB_ZIPOPEN ) { - char* szFileName = hb_parc( 1 ); + const char* szFileName = hb_parc( 1 ); if( szFileName ) { @@ -179,7 +180,7 @@ HB_FUNC( HB_ZIPCLOSE ) [ cPassword ], [ cComment ] ) --> nError */ HB_FUNC( HB_ZIPFILECREATE ) { - char* szZipName = hb_parc( 2 ); + const char* szZipName = hb_parc( 2 ); if( szZipName ) { @@ -220,7 +221,7 @@ HB_FUNC( HB_ZIPFILECREATE ) /* HB_ZipFileWrite( hZip, cData [, nLen ] ) --> nError */ HB_FUNC( HB_ZIPFILEWRITE ) { - char* pData = hb_parc( 2 ); + const char* pData = hb_parc( 2 ); if( pData ) { @@ -251,7 +252,7 @@ HB_FUNC( HB_ZIPFILECLOSE ) /* HB_UnzipOpen( cFileName ) --> hUnzip */ HB_FUNC( HB_UNZIPOPEN ) { - char* szFileName = hb_parc( 1 ); + const char* szFileName = hb_parc( 1 ); if( szFileName ) { @@ -508,7 +509,7 @@ HB_FUNC( HB_UNZIPFILECLOSE ) * */ -static int hb_zipStoreFile( zipFile hZip, char* szFileName, char* szName, char* szPassword, char* szComment ) +static int hb_zipStoreFile( zipFile hZip, const char* szFileName, const char* szName, const char* szPassword, const char* szComment ) { char * szZipName, * pString; FHANDLE hFile; @@ -788,8 +789,8 @@ static int hb_zipStoreFile( zipFile hZip, char* szFileName, char* szName, char* szPassword, 0 ); if( iResult == 0 ) { - pString = (char*) hb_xgrab( 1024 * 16 ); - while ( ( ulLen = hb_fsReadLarge( hFile, (BYTE*) pString, 1024 * 16 ) ) > 0 ) + pString = ( char* ) hb_xgrab( HB_Z_IOBUF_SIZE ); + while( ( ulLen = hb_fsReadLarge( hFile, (BYTE*) pString, HB_Z_IOBUF_SIZE ) ) > 0 ) { zipWriteInFileInZip( hZip, pString, ulLen ); } @@ -812,7 +813,7 @@ static int hb_zipStoreFile( zipFile hZip, char* szFileName, char* szName, char* /* HB_ZipStoreFile( hZip, cFileName, [ cZipName ], [ cPassword ], [ cComment ] ) --> nError */ HB_FUNC( HB_ZIPSTOREFILE ) { - char* szFileName = hb_parc( 2 ); + const char* szFileName = hb_parc( 2 ); if( szFileName ) { @@ -826,7 +827,7 @@ HB_FUNC( HB_ZIPSTOREFILE ) } -static int hb_unzipExtractCurrentFile( unzFile hUnzip, char* szFileName, char* szPassword ) +static int hb_unzipExtractCurrentFile( unzFile hUnzip, const char* szFileName, const char* szPassword ) { char szName[ _POSIX_PATH_MAX + 1 ]; ULONG ulPos, ulLen; @@ -881,9 +882,9 @@ static int hb_unzipExtractCurrentFile( unzFile hUnzip, char* szFileName, char* s if( hFile != FS_ERROR ) { - pString = (char*) hb_xgrab( 1024 * 16 ); + pString = (char*) hb_xgrab( HB_Z_IOBUF_SIZE ); - while ( ( iResult = unzReadCurrentFile( hUnzip, pString, 16 * 1024 ) ) > 0 ) + while( ( iResult = unzReadCurrentFile( hUnzip, pString, HB_Z_IOBUF_SIZE ) ) > 0 ) { hb_fsWriteLarge( hFile, (BYTE*) pString, (ULONG) iResult ); } @@ -1025,3 +1026,215 @@ HB_FUNC( HB_UNZIPEXTRACTCURRENTFILE ) if( hUnzip ) hb_retni( hb_unzipExtractCurrentFile( hUnzip, hb_parc( 2 ), hb_parc( 3 ) ) ); } + + +static int hb_zipDeleteFile( const char* szZipFile, const char* szFileMask ) +{ + char szTempFile[ _POSIX_PATH_MAX + 1 ]; + char szCurrFile[ _POSIX_PATH_MAX + 1 ]; + PHB_FNAME pFileName; + FHANDLE hFile; + unzFile hUnzip; + zipFile hZip; + unz_global_info ugi; + unz_file_info ufi; + zip_fileinfo zfi; + char* pszGlobalComment = NULL; + char* pszFileComment = NULL; + void* pExtraField = NULL; + void* pLocalExtraField = NULL; + int iFilesLeft = 0; + int iFilesDel = 0; + int iExtraFieldLen; + int method; + int level; + int iResult; + + /* open source file */ + hUnzip = unzOpen( szZipFile ); + if( hUnzip == NULL ) + return UNZ_ERRNO; + + pFileName = hb_fsFNameSplit( szZipFile ); + hFile = hb_fsCreateTemp( ( BYTE * ) pFileName->szPath, NULL, FC_NORMAL, ( BYTE * ) szTempFile ); + hZip = NULL; + if( hFile != FS_ERROR ) + { + hb_fsClose( hFile ); + hZip = zipOpen( szTempFile, APPEND_STATUS_CREATE ); + } + hb_xfree( pFileName ); + + if( hZip == NULL ) + { + unzClose( hUnzip ); + return UNZ_ERRNO; + } + + iResult = unzGetGlobalInfo( hUnzip, &ugi ); + if( iResult == UNZ_OK ) + { + if( ugi.size_comment > 0 ) + { + pszGlobalComment = ( char * ) hb_xgrab( ugi.size_comment + 1 ); + if( ( uLong ) unzGetGlobalComment( hUnzip, pszGlobalComment, + ugi.size_comment ) != ugi.size_comment ) + iResult = UNZ_ERRNO; + pszGlobalComment[ ugi.size_comment ] = '\0'; + } + if( iResult == UNZ_OK ) + iResult = unzGoToFirstFile( hUnzip ); + } + + while( iResult == UNZ_OK ) + { + iResult = unzGetCurrentFileInfo( hUnzip, &ufi, szCurrFile, _POSIX_PATH_MAX, NULL, 0, NULL, 0 ); + if( iResult != UNZ_OK ) + break; + + if( hb_strMatchFile( szCurrFile, szFileMask ) ) + iFilesDel++; + else + { + if( ufi.size_file_extra ) + pExtraField = ( char * ) hb_xgrab( ufi.size_file_extra ); + if( ufi.size_file_comment ) + pszFileComment = ( char * ) hb_xgrab( ufi.size_file_comment + 1 ); + + iResult = unzGetCurrentFileInfo( hUnzip, NULL, NULL, 0, + pExtraField, ufi.size_file_extra, + pszFileComment, ufi.size_file_comment ); + pszFileComment[ ufi.size_file_comment ] = '\0'; + if( iResult != UNZ_OK ) + break; + + iResult = unzOpenCurrentFile2( hUnzip, &method, &level, 1 ); + if( iResult != UNZ_OK ) + break; + + iExtraFieldLen = unzGetLocalExtrafield( hUnzip, NULL, 0 ); + if( iExtraFieldLen < 0 ) + { + iResult = UNZ_ERRNO; + break; + } + else if( iExtraFieldLen > 0 ) + { + pLocalExtraField = hb_xgrab( iExtraFieldLen ); + if( unzGetLocalExtrafield( hUnzip, pLocalExtraField, iExtraFieldLen ) != iExtraFieldLen ) + { + iResult = UNZ_ERRNO; + break; + } + } + + memset( &zfi, 0, sizeof( zfi ) ); + memcpy( &zfi.tmz_date, &ufi.tmu_date, sizeof( tm_unz ) ); + zfi.dosDate = ufi.dosDate; + zfi.internal_fa = ufi.internal_fa; + zfi.external_fa = ufi.external_fa; + + iResult = zipOpenNewFileInZip2( hZip, szCurrFile, &zfi, pLocalExtraField, iExtraFieldLen, pExtraField, ufi.size_file_extra, pszFileComment, method, level, 1 ); + if( iResult != UNZ_OK ) + break; + + if( ufi.compressed_size ) + { + BYTE * buffer = ( BYTE * ) hb_xgrab( HB_Z_IOBUF_SIZE ); + uLong ulLeft = ufi.compressed_size; + + while( ulLeft > 0 ) + { + int iRead = HB_MIN( ulLeft, HB_Z_IOBUF_SIZE ); + iResult = unzReadCurrentFile( hUnzip, ( voidp ) buffer, iRead ); + if( iResult < 0 ) + break; + if( iResult != iRead ) + { + iResult = UNZ_ERRNO; + break; + } + iResult = zipWriteInFileInZip( hZip, ( voidp ) buffer, iRead ); + if( iResult != UNZ_OK ) + break; + ulLeft -= iRead; + } + hb_xfree( buffer ); + if( iResult != UNZ_OK ) + break; + } + + iResult = zipCloseFileInZipRaw( hZip, ufi.uncompressed_size, ufi.crc ); + if( iResult != UNZ_OK ) + break; + + iResult = unzCloseCurrentFile( hUnzip ); + if( iResult != UNZ_OK ) + break; + + if( pExtraField ) + { + hb_xfree( pExtraField ); + pExtraField = NULL; + } + if( pszFileComment ) + { + hb_xfree( pszFileComment ); + pszFileComment = NULL; + } + if( pLocalExtraField ) + { + hb_xfree( pLocalExtraField ); + pLocalExtraField = NULL; + } + iFilesLeft++; + } + iResult = unzGoToNextFile( hUnzip ); + } + + if( pExtraField ) + hb_xfree( pExtraField ); + if( pszFileComment ) + hb_xfree( pszFileComment ); + if( pLocalExtraField ) + hb_xfree( pLocalExtraField ); + + if( iFilesDel == 0 ) + iResult = UNZ_ERRNO; + else if( iResult == UNZ_END_OF_LIST_OF_FILE ) + iResult = UNZ_OK; + + if( iResult != UNZ_OK ) + zipClose( hZip, NULL ); + else + iResult = zipClose( hZip, pszGlobalComment ); + unzClose( hUnzip ); + if( pszGlobalComment ) + hb_xfree( pszGlobalComment ); + + if( iResult != UNZ_OK ) + hb_fsDelete( ( BYTE * ) szTempFile ); + else + { + hb_fsDelete( ( BYTE * ) szZipFile ); + + if( iFilesLeft == 0 ) + hb_fsDelete( ( BYTE * ) szTempFile ); + else if( !hb_fsRename( ( BYTE * ) szTempFile, ( BYTE * ) szZipFile ) ) + iResult = UNZ_ERRNO; + } + + return iResult; +} + +/* HB_ZipDeleteFile( cZipFile, cFileMask ) --> nError */ +HB_FUNC( HB_ZIPDELETEFILE ) +{ + char * szZipFile = hb_parc( 1 ); + char * szFileMask = hb_parc( 2 ); + + if( szZipFile && szFileMask ) + hb_retni( hb_zipDeleteFile( szZipFile, szFileMask ) ); + else + hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} diff --git a/harbour/contrib/hbmzip/readme.txt b/harbour/contrib/hbmzip/readme.txt index 31322efeeb..7659249960 100644 --- a/harbour/contrib/hbmzip/readme.txt +++ b/harbour/contrib/hbmzip/readme.txt @@ -50,7 +50,7 @@ HB_ZipFileCreate( hZip, cZipName, dDate, cTime, nInternalAttr, nExternalAttr, [ nMethod = HB_ZLIB_METHOD_DEFLATE ], [ nLevel = HB_ZLIB_COMPRESSION_DEFAULT ], - [ cPassword ], [ cComment ] ) --> nError */ + [ cPassword ], [ cComment ] ) --> nError HB_ZipFileWrite( hZip, cData [, nLen ] ) --> nError HB_ZipFileClose( hZip ) --> nError HB_ZipStoreFile( hZip, cFileName, [ cZipName ], ; @@ -67,8 +67,11 @@ HB_UnzipFileGoto( hUnzip, nPosition ) --> nError HB_UnzipFileInfo( hUnzip, @cZipName, @dDate, @cTime, @nInternalAttr, @nExternalAttr, @nMethod, @nSize, @nCompressedSize, - @cComment ) --> nError */ + @cComment ) --> nError HB_UnzipFileOpen( hUnzip, [ cPassword ] ) --> nError HB_UnzipFileRead( hUnzip, @cBuf [, nLen ] ) --> nRead HB_UnzipFileClose( hUnzip ) --> nError HB_UnzipExtractCurrentFile( hZip, [ cFileName ], [ cPassword ] ) --> nError + + +HB_ZipDeleteFile( cZipFile, cFileMask ) --> nError diff --git a/harbour/contrib/hbmzip/zip.c b/harbour/contrib/hbmzip/zip.c index 4ffeadec61..b9a549dceb 100644 --- a/harbour/contrib/hbmzip/zip.c +++ b/harbour/contrib/hbmzip/zip.c @@ -544,6 +544,7 @@ extern zipFile ZEXPORT zipOpen2 ( ziinit.begin_pos = ZTELL(ziinit.z_filefunc,ziinit.filestream); ziinit.in_opened_file_inzip = 0; ziinit.ci.stream_initialised = 0; + ziinit.ci.stream.data_type = 0; ziinit.number_entry = 0; ziinit.add_position_when_writting_offset = 0; init_linkedlist(&(ziinit.central_dir)); diff --git a/harbour/contrib/xhb/dirrec.prg b/harbour/contrib/xhb/dirrec.prg index 5d96fa22b6..b3832a1254 100644 --- a/harbour/contrib/xhb/dirrec.prg +++ b/harbour/contrib/xhb/dirrec.prg @@ -72,41 +72,19 @@ FUNCTION DirectoryRecurse( cPath, cAttr ) - LOCAL aResult := {}, aDir, aFile, cExt, cMask, cPathSep + LOCAL aResult + LOCAL cFilePath, cExt, cMask - IF Empty( cPath ) - cPath := "" - cMask := hb_osFileMask() - ELSE - hb_FNameSplit( cPath, @cPath, @cMask, @cExt ) - cMask += cExt - IF cMask == "" - cMask := hb_osFileMask() - ENDIF - ENDIF + hb_FNameSplit( cPath, @cFilePath, @cMask, @cExt ) + cMask += cExt - IF ! ValType( cAttr ) $ "CM" - cAttr := "" - ENDIF + /* The trick with StrTran() below if for strict xHarbour + * compatibility though it should be reverted when it will + * be fixed in xHarbour + */ + aResult := HB_DirScan( cFilePath, cMask + cExt, ; + StrTran( Upper( cAttr ), "D" ) ) - cPathSep := hb_osPathSeparator() - /* xHarbour does not add "D" to attribute list */ - aDir := Directory( cPath + cMask, cAttr + "D" ) - - FOR EACH aFile IN aDir - IF "D" $ aFile[ 5 ] - /* xHarbour does not respect "D" in attribute list */ - IF "D" $ cAttr - AAdd( aResult, aFile ) - ENDIF - IF !( aFile[ 1 ] == "." .OR. aFile[ 1 ] == ".." ) - AEval( DirectoryRecurse( cPath + aFile[ 1 ] + cPathSep + cMask, cAttr ), ; - { |x| x[ 1 ] := aFile[ 1 ] + cPathSep + x[ 1 ], ; - AAdd( aResult, x ) } ) - ENDIF - ELSE - AAdd( aResult, aFile ) - ENDIF - NEXT + AEval( aResult, { |x| x[ 1 ] := cFilePath + x[ 1 ] } ) RETURN aResult diff --git a/harbour/include/hbextern.ch b/harbour/include/hbextern.ch index 99111ffeff..1a1830212e 100644 --- a/harbour/include/hbextern.ch +++ b/harbour/include/hbextern.ch @@ -795,6 +795,7 @@ EXTERNAL HB_FILEEXISTS EXTERNAL HB_DIREXISTS EXTERNAL HB_FNAMEMERGE EXTERNAL HB_FNAMESPLIT +EXTERNAL HB_DIRSCAN EXTERNAL HB_LANGNAME EXTERNAL HB_LANGSELECT EXTERNAL HB_LANGERRMSG @@ -837,7 +838,6 @@ EXTERNAL HB_IDLESTATE EXTERNAL HB_RELEASECPU EXTERNAL HB_OSNEWLINE -EXTERNAL HB_OSFILEMASK EXTERNAL HB_APARAMS EXTERNAL HB_PVALUE EXTERNAL HB_FORNEXT @@ -846,6 +846,7 @@ EXTERNAL HB_METHODNAME EXTERNAL HB_SETMACRO EXTERNAL HB_STOD EXTERNAL HB_WILDMATCH +EXTERNAL HB_FILEMATCH EXTERNAL HB_CLOCKS2SECS EXTERNAL HB_MATHERMODE EXTERNAL HB_MATHERBLOCK @@ -1053,6 +1054,7 @@ EXTERNAL HB_OSDRIVESEPARATOR EXTERNAL HB_OSPATHDELIMITERS EXTERNAL HB_OSPATHLISTSEPARATOR EXTERNAL HB_OSPATHSEPARATOR +EXTERNAL HB_OSFILEMASK EXTERNAL HB_SETKEYARRAY EXTERNAL HB_SETKEYCHECK EXTERNAL HB_SETKEYGET diff --git a/harbour/source/rtl/Makefile b/harbour/source/rtl/Makefile index b4474c4de9..d39f80629b 100644 --- a/harbour/source/rtl/Makefile +++ b/harbour/source/rtl/Makefile @@ -170,6 +170,7 @@ PRG_SOURCES=\ dbedit.prg \ devoutp.prg \ dircmd.prg \ + dirscan.prg \ einstv52.prg \ einstvar.prg \ einstvau.prg \ diff --git a/harbour/source/rtl/dirscan.prg b/harbour/source/rtl/dirscan.prg new file mode 100644 index 0000000000..1c2f03c629 --- /dev/null +++ b/harbour/source/rtl/dirscan.prg @@ -0,0 +1,96 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * HB_DirScan() + * + * Copyright 2008 Przemyslaw Czerpak + * www - http://www.harbour-project.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ + +STATIC FUNCTION HB_doScan( cPath, cMask, cAttr, cPathSep ) + + LOCAL aResult, aFile + LOCAL lMatch + + aResult := {} + + FOR EACH aFile IN Directory( cPath + hb_osFileMask(), cAttr + "D" ) + lMatch = HB_FileMatch( aFile[ 1 ], cMask ) + IF "D" $ aFile[ 5 ] + IF lMatch .AND. "D" $ cAttr + AAdd( aResult, aFile ) + ENDIF + IF !( aFile[ 1 ] == "." .OR. aFile[ 1 ] == ".." .OR. aFile[ 1 ] == "" ) + AEval( HB_DoScan( cPath + aFile[ 1 ] + cPathSep, cMask, cAttr, cPathSep ), ; + { |x| x[ 1 ] := aFile[ 1 ] + cPathSep + x[ 1 ], ; + AAdd( aResult, x ) } ) + ENDIF + ELSEIF lMatch + AAdd( aResult, aFile ) + ENDIF + NEXT + + RETURN aResult + +FUNCTION HB_DirScan( cPath, cFileMask, cAttr ) + + LOCAL cFilePath, cPathSep + + cPathSep := hb_osPathSeparator() + + IF Empty( cPath ) + cFilePath := "" + ELSE + cFilePath := cPath + IF !Right( cPath, 1 ) $ hb_osPathDelimiters() + cFilePath += cPathSep + ENDIF + ENDIF + + RETURN HB_DoScan( cFilePath, ; + IIF( Empty( cFileMask ), hb_osFileMask(), cFileMask ), ; + IIF( ValType( cAttr ) $ "CM", cAttr, "" ), ; + cPathSep ) diff --git a/harbour/source/rtl/strmatch.c b/harbour/source/rtl/strmatch.c index a726fb5249..e75bbba8f8 100644 --- a/harbour/source/rtl/strmatch.c +++ b/harbour/source/rtl/strmatch.c @@ -320,3 +320,9 @@ HB_FUNC( HB_WILDMATCH ) hb_parl( 3 ) ? hb_strMatchWildExact( hb_parc( 2 ), hb_parc( 1 ) ) : hb_strMatchWild( hb_parc( 2 ), hb_parc( 1 ) ) ); } + +HB_FUNC( HB_FILEMATCH ) +{ + hb_retl( ( ! ISCHAR( 1 ) || ! ISCHAR( 2 ) ) ? FALSE : + hb_strMatchFile( hb_parc( 1 ), hb_parc( 2 ) ) ); +}