diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 16ba3539e6..9f74d51355 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,32 @@ +2001-11-28 19:45 UTC-0500 David G. Holm + + * include/hbapifs.h + + Moved PATHNAMES support from include/hbpp.h. + + * include/hbpp.h + - Moved PATHNAMES support into include/hbapifs.h + + * include/hbset.h + + Added PATHNAMES support for SET PATH. + + * source/common/hbfsapi.c + + Moved PATHNAMES support from source/compiler/cmdcheck.c + + * source/compiler/cmdcheck.c + - Moved PATHNAMES support into source/common/hbfsapi.c + + * source/rtl/Makefile + + Added spfiles.c + + * source/rtl/philes.c + ! FILES uses the new search path file API. + + * source/rtl/set.c + + Added PATHNAMES support for SET PATH. + + + source/rtl/spfiles.c + + New search path file API functions. + 2001-11-28 22:45 GMT+1 JFL (mafact) * harbour/source/vm/classes.c * Now releasing Classes from the last one to check Bryan GPF diff --git a/harbour/include/hbapifs.h b/harbour/include/hbapifs.h index d31e39536b..9e53c0b60f 100644 --- a/harbour/include/hbapifs.h +++ b/harbour/include/hbapifs.h @@ -131,6 +131,18 @@ typedef struct extern PHB_FNAME hb_fsFNameSplit( char * pszFileName ); /* Split given filename into path, name and extension */ extern char * hb_fsFNameMerge( char * pszFileName, PHB_FNAME pFileName ); /* This function joins path, name and extension into a string with a filename */ +/* Searchable path support */ +typedef struct _PATHNAMES +{ + char * szPath; + struct _PATHNAMES * pNext; +} PATHNAMES; +void hb_fsAddSearchPath( char * szPath, PATHNAMES * * pSearchList ); +FHANDLE hb_spFile( BYTE * pFilename ); +FHANDLE hb_spOpen( BYTE * pFilename, USHORT uiFlags ); +FHANDLE hb_spCreate( BYTE * pFilename, USHORT uiAttr ); +FHANDLE hb_spCreateEx( BYTE * pFilename, USHORT uiAttr, USHORT uiFlags ); + #if defined(HB_EXTERN_C) } #endif diff --git a/harbour/include/hbpp.h b/harbour/include/hbpp.h index 0c67bfc144..aaee5658d0 100644 --- a/harbour/include/hbpp.h +++ b/harbour/include/hbpp.h @@ -62,13 +62,6 @@ extern "C" { #endif -/* the list of pathnames to search with #include */ -typedef struct _PATHNAMES -{ - char * szPath; - struct _PATHNAMES * pNext; -} PATHNAMES; - struct _DEFINES; typedef struct _DEFINES { diff --git a/harbour/include/hbset.h b/harbour/include/hbset.h index 71af2a1b21..ca02f15531 100644 --- a/harbour/include/hbset.h +++ b/harbour/include/hbset.h @@ -190,6 +190,7 @@ extern HB_SET_STRUCT hb_set; extern void hb_setInitialize( void ); extern void hb_setRelease( void ); +extern PATHNAMES * hb_setGetFirstSetPath( void ); typedef enum { diff --git a/harbour/source/common/hbfsapi.c b/harbour/source/common/hbfsapi.c index 95a5028d46..714942057c 100644 --- a/harbour/source/common/hbfsapi.c +++ b/harbour/source/common/hbfsapi.c @@ -71,7 +71,45 @@ extern void _RTLENTRY _init_streams(void); #pragma startup _init_streams 5 #endif +/* + * Function that adds at most one path to a list of pathnames to search + */ +static void AddSearchPath( char * szPath, PATHNAMES * * pSearchList ) +{ + PATHNAMES * pPath = *pSearchList; + if( pPath ) + { + while( pPath->pNext ) + pPath = pPath->pNext; + + pPath->pNext = ( PATHNAMES * ) hb_xgrab( sizeof( PATHNAMES ) ); + pPath = pPath->pNext; + } + else + *pSearchList = pPath = ( PATHNAMES * ) hb_xgrab( sizeof( PATHNAMES ) ); + + pPath->pNext = NULL; + pPath->szPath = szPath; +} + +/* + * Function that adds zero or more paths to a list of pathnames to search + */ +void hb_fsAddSearchPath( char * szPath, PATHNAMES * * pSearchList ) +{ + char * pPath; + char * pDelim; + + pPath = hb_strdup( szPath ); + while( ( pDelim = strchr( pPath, OS_PATH_LIST_SEPARATOR ) ) != NULL ) + { + * pDelim = '\0'; + AddSearchPath( pPath, pSearchList ); + pPath = pDelim + 1; + } + AddSearchPath( pPath, pSearchList ); +} /* Split given filename into path, name and extension, plus determine drive */ PHB_FNAME hb_fsFNameSplit( char * pszFileName ) diff --git a/harbour/source/compiler/cmdcheck.c b/harbour/source/compiler/cmdcheck.c index d2f0b9c290..e136f8addd 100644 --- a/harbour/source/compiler/cmdcheck.c +++ b/harbour/source/compiler/cmdcheck.c @@ -55,27 +55,6 @@ extern int hb_pp_ParseDefine( char * ); -r -t || getenv( "TMP" ) */ -/* - * Function that adds specified path to the list of pathnames to search list - */ -static void AddSearchPath( char * szPath, PATHNAMES * * pSearchList ) -{ - PATHNAMES * pPath = *pSearchList; - - if( pPath ) - { - while( pPath->pNext ) - pPath = pPath->pNext; - - pPath->pNext = ( PATHNAMES * ) hb_xgrab( sizeof( PATHNAMES ) ); - pPath = pPath->pNext; - } - else - *pSearchList = pPath = ( PATHNAMES * ) hb_xgrab( sizeof( PATHNAMES ) ); - - pPath->pNext = NULL; - pPath->szPath = szPath; -} /* NOTE: Making the date and time info to fit into 32 bits can only be done in a "lossy" way, in practice that means it's not possible to unpack @@ -603,19 +582,7 @@ void hb_compChkEnvironVar( char * szSwitch ) */ case 'i': case 'I': - { - char * pPath; - char * pDelim; - - pPath = hb_strdup( s + 1 ); - while( ( pDelim = strchr( pPath, OS_PATH_LIST_SEPARATOR ) ) != NULL ) - { - * pDelim = '\0'; - AddSearchPath( pPath, &hb_comp_pIncludePath ); - pPath = pDelim + 1; - } - AddSearchPath( pPath, &hb_comp_pIncludePath ); - } + hb_fsAddSearchPath( s + 1, &hb_comp_pIncludePath ); break; case 'k': @@ -811,17 +778,7 @@ void hb_compChkPaths( void ) if( szInclude ) { - char * pPath; - char * pDelim; - - pPath = szInclude = hb_strdup( szInclude ); - while( ( pDelim = strchr( pPath, OS_PATH_LIST_SEPARATOR ) ) != NULL ) - { - *pDelim = '\0'; - AddSearchPath( pPath, &hb_comp_pIncludePath ); - pPath = pDelim + 1; - } - AddSearchPath( pPath, &hb_comp_pIncludePath ); + hb_fsAddSearchPath( szInclude, &hb_comp_pIncludePath ); } } diff --git a/harbour/source/rtl/Makefile b/harbour/source/rtl/Makefile index 0c83dd2394..65d477d575 100644 --- a/harbour/source/rtl/Makefile +++ b/harbour/source/rtl/Makefile @@ -91,6 +91,7 @@ C_SOURCES=\ shadow.c \ soundex.c \ space.c \ + spfiles.c \ str.c \ strcase.c \ strings.c \ diff --git a/harbour/source/rtl/philes.c b/harbour/source/rtl/philes.c index 1ab701ead7..50c666f20c 100644 --- a/harbour/source/rtl/philes.c +++ b/harbour/source/rtl/philes.c @@ -52,6 +52,7 @@ #include "hbapi.h" #include "hbapifs.h" #include "hbapierr.h" +#include "hbset.h" HB_FUNC( FOPEN ) { @@ -176,7 +177,7 @@ HB_FUNC( FSEEK ) HB_FUNC( FILE ) { - hb_retl( ISCHAR( 1 ) ? hb_fsFile( ( BYTE * ) hb_parc( 1 ) ) : FALSE ); + hb_retl( ISCHAR( 1 ) ? hb_spFile( hb_parc( 1 ) ) : FALSE ); } HB_FUNC( FREADSTR ) diff --git a/harbour/source/rtl/set.c b/harbour/source/rtl/set.c index fd7a41ad31..e54303e795 100644 --- a/harbour/source/rtl/set.c +++ b/harbour/source/rtl/set.c @@ -6,7 +6,7 @@ * Harbour Project source code: * Set functions * - * Copyright 1999 David G. Holm + * Copyright 1999-2001 David G. Holm * www - http://www.harbour-project.org * * This program is free software; you can redistribute it and/or modify @@ -73,6 +73,29 @@ static PHB_SET_LISTENER sp_sl_first; static PHB_SET_LISTENER sp_sl_last; static int s_next_listener; +static PATHNAMES * sp_set_path; + +static void hb_setFreeSetPath( void ) +{ + /* Free all set paths */ + PATHNAMES * curPath = sp_set_path; + PATHNAMES * nextPath; + while( curPath ) + { + nextPath = curPath->pNext; + hb_xfree( curPath ); + curPath = nextPath; + } + if( sp_set_path ) + { + /* Only the first path holds an allocated string. + All of the other paths in the list are part of + that first string. */ + hb_xfree( sp_set_path->szPath ); + sp_set_path = NULL; + } +} + static BOOL set_logical( PHB_ITEM pItem ) { BOOL bLogical = FALSE; @@ -609,7 +632,12 @@ HB_FUNC( SET ) case HB_SET_PATH : if( hb_set.HB_SET_PATH ) hb_retc( hb_set.HB_SET_PATH ); else hb_retc( "" ); - if( args > 1 ) hb_set.HB_SET_PATH = set_string( pArg2, hb_set.HB_SET_PATH ); + if( args > 1 ) + { + hb_setFreeSetPath(); + hb_set.HB_SET_PATH = set_string( pArg2, hb_set.HB_SET_PATH ); + hb_fsAddSearchPath( hb_set.HB_SET_PATH, &sp_set_path ); + } break; case HB_SET_PRINTER : hb_retl( hb_set.HB_SET_PRINTER ); @@ -797,7 +825,7 @@ void hb_setRelease( void ) if( hb_set.HB_SET_PRINTFILE ) hb_xfree( hb_set.HB_SET_PRINTFILE ); hb_set.HB_SET_TYPEAHEAD = -1; hb_inkeyReset( TRUE ); /* Free keyboard typeahead buffer */ - + while( sp_sl_first ) { /* Free all set listeners */ @@ -805,6 +833,8 @@ void hb_setRelease( void ) hb_xfree( sp_sl_first ); sp_sl_first = sp_sl_last; } + + hb_setFreeSetPath(); } int hb_setListenerAdd( HB_SET_LISTENER_CALLBACK * callback ) @@ -850,3 +880,8 @@ int hb_setListenerRemove( int listener ) } return listener; } + +PATHNAMES * hb_setGetFirstSetPath( void ) +{ + return sp_set_path; +} diff --git a/harbour/source/rtl/spfiles.c b/harbour/source/rtl/spfiles.c new file mode 100644 index 0000000000..f24ce19df2 --- /dev/null +++ b/harbour/source/rtl/spfiles.c @@ -0,0 +1,170 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * A search path shim for the FileSys API (C level) + * + * Copyright 2001 David G. Holm + * 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. + * + */ + +#include "hbapifs.h" +#include "hbset.h" + +static BOOL FindFile( BYTE * pFilename, BYTE * path ) +{ + BOOL bIsFile = FALSE; + PHB_FNAME pFilepath; + + HB_TRACE(HB_TR_DEBUG, ("FindFile(%s, %p)", (char*) pFilename, path)); + + pFilepath = hb_fsFNameSplit( pFilename ); + if( pFilepath->szPath ) + { + hb_fsFNameMerge( path, pFilepath ); + bIsFile = hb_fsFile( path ); + } + else + { + if( hb_set.HB_SET_DEFAULT ) + { + pFilepath->szPath = hb_set.HB_SET_DEFAULT; + hb_fsFNameMerge( path, pFilepath ); + bIsFile = hb_fsFile( path ); + } + + if( !bIsFile && hb_set.HB_SET_PATH ) + { + PATHNAMES * nextPath = hb_setGetFirstSetPath(); + while( !bIsFile && nextPath ) + { + pFilepath->szPath = nextPath->szPath; + hb_fsFNameMerge( path, pFilepath ); + bIsFile = hb_fsFile( path ); + nextPath = nextPath->pNext; + } + } + } + hb_xfree( pFilepath ); + + if( !bIsFile ) + * path = '\0'; + + return bIsFile; +} + +BOOL hb_spFile( BYTE * pFilename ) +{ + BYTE path[ _POSIX_PATH_MAX + 1 ]; + + HB_TRACE(HB_TR_DEBUG, ("hb_spFile(%s, %p)", (char*) pFilename, path)); + + return FindFile( pFilename, path ); +} + +FHANDLE hb_spOpen( BYTE * pFilename, USHORT uiFlags ) +{ + FHANDLE hFileHandle = -1; + BYTE path[ _POSIX_PATH_MAX + 1 ]; + + HB_TRACE(HB_TR_DEBUG, ("hb_spOpen(%p, %hu)", pFilename, uiFlags)); + + if( FindFile( pFilename, path ) ) + { + hFileHandle = hb_fsOpen( path, uiFlags ); + } + else + { + hFileHandle = hb_fsOpen( pFilename, uiFlags ); + } + + return hFileHandle; +} + +FHANDLE hb_spCreate( BYTE * pFilename, USHORT uiAttr ) +{ + FHANDLE hFileHandle = -1; + + HB_TRACE(HB_TR_DEBUG, ("hb_spCreate(%p, %hu)", pFilename, uiAttr)); + + if( ISCHAR( 1 ) ) + { + BYTE path[ _POSIX_PATH_MAX + 1 ]; + PHB_FNAME pFilepath = hb_fsFNameSplit( pFilename ); + + if( ! pFilepath->szPath && hb_set.HB_SET_DEFAULT ) + pFilepath->szPath = hb_set.HB_SET_DEFAULT; + + hb_fsFNameMerge( path, pFilepath ); + hb_xfree( pFilepath ); + + hFileHandle = hb_fsCreate( path, uiAttr ); + } + + return hFileHandle; +} + +FHANDLE hb_spCreateEx( BYTE * pFilename, USHORT uiAttr, USHORT uiFlags ) +{ + FHANDLE hFileHandle; + + HB_TRACE(HB_TR_DEBUG, ("hb_spCreateEx(%p, %hu, %hu)", pFilename, uiAttr, uiFlags)); + + if( ISCHAR( 1 ) ) + { + BYTE path[ _POSIX_PATH_MAX + 1 ]; + PHB_FNAME pFilepath = hb_fsFNameSplit( pFilename ); + + if( ! pFilepath->szPath && hb_set.HB_SET_DEFAULT ) + pFilepath->szPath = hb_set.HB_SET_DEFAULT; + + hb_fsFNameMerge( path, pFilepath ); + hb_xfree( pFilepath ); + + hFileHandle = hb_fsCreateEx( path, uiAttr, uiFlags ); + } + + return hFileHandle; +}