diff --git a/harbour/ChangeLog b/harbour/ChangeLog index aa6350ae3a..23f9e0a943 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,27 @@ 2009-12-31 13:59 UTC+0100 Foo Bar (foo.bar foobar.org) */ +2009-02-11 02:38 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/include/hbapi.h + * harbour/source/vm/cmdarg.c + + added const char * hb_cmdargARGVN( int argc ) + + * harbour/source/vm/cmdarg.c + * try to convert executable file name argument in argv[0] to + absolute path if it's relative one. Respect PATH envvar it necessary. + + * harbour/source/common/hbdate.c + * formatting + + * harbour/source/rtl/philes.c + * harbour/source/rtl/errorint.c + * harbour/source/rtl/filesys.c + ! use hb_cmdargARGVN(n) instead of hb_cmdargARGV()[n] to avoid + possible GPF if some function will be called before argument + initialization + * removed additional logic which tries to convert relative paths + in file name from hb_fsBaseDirBuff() and HB_PROGNAME() functions + 2009-02-10 10:35 UTC+0100 Viktor Szakats (harbour.01 syenar hu) * source/rtl/filesys.c ! Fixes for *NIX compilation to latest change. diff --git a/harbour/include/hbapi.h b/harbour/include/hbapi.h index 670ece2f67..f50e1a2115 100644 --- a/harbour/include/hbapi.h +++ b/harbour/include/hbapi.h @@ -904,13 +904,14 @@ extern HB_EXPORT PHB_SYMB hb_symbolNew( const char * szName ); /* create a new /* Command line and environment argument management */ extern HB_EXPORT void hb_cmdargInit( int argc, char * argv[] ); /* initialize command line argument API's */ -extern int hb_cmdargARGC( void ); /* retrieve command line argument count */ -extern char ** hb_cmdargARGV( void ); /* retrieve command line argument buffer pointer */ -extern BOOL hb_cmdargIsInternal( const char * szArg, int * piLen ); /* determine if a string is an internal setting */ -extern BOOL hb_cmdargCheck( const char * pszName ); /* Check if a given internal switch (like //INFO) was set */ -extern char * hb_cmdargString( const char * pszName ); /* Returns the string value of an internal switch (like //TEMPPATH:"C:\") */ -extern int hb_cmdargNum( const char * pszName ); /* Returns the numeric value of an internal switch (like //F:90) */ -extern ULONG hb_cmdargProcessVM( int*, int* ); /* Check for command line internal arguments */ +extern int hb_cmdargARGC( void ); /* retrieve command line argument count */ +extern char ** hb_cmdargARGV( void ); /* retrieve command line argument buffer pointer */ +extern const char * hb_cmdargARGVN( int argc ); /* retrieve given command line argument */ +extern BOOL hb_cmdargIsInternal( const char * szArg, int * piLen ); /* determine if a string is an internal setting */ +extern BOOL hb_cmdargCheck( const char * pszName ); /* Check if a given internal switch (like //INFO) was set */ +extern char * hb_cmdargString( const char * pszName ); /* Returns the string value of an internal switch (like //TEMPPATH:"C:\") */ +extern int hb_cmdargNum( const char * pszName ); /* Returns the numeric value of an internal switch (like //F:90) */ +extern ULONG hb_cmdargProcessVM( int*, int* ); /* Check for command line internal arguments */ #if defined( HB_OS_WIN ) && defined( HB_OS_WIN_USED ) extern HB_EXPORT void hb_winmainArgInit( HANDLE hInstance, HANDLE hPrevInstance, int iCmdShow ); /* Set WinMain() parameters */ extern HB_EXPORT BOOL hb_winmainArgGet( HANDLE * phInstance, HANDLE * phPrevInstance, int * piCmdShow ); /* Retrieve WinMain() parameters */ diff --git a/harbour/source/common/hbdate.c b/harbour/source/common/hbdate.c index e519c73a63..158598e54b 100644 --- a/harbour/source/common/hbdate.c +++ b/harbour/source/common/hbdate.c @@ -350,7 +350,7 @@ LONG hb_timeStampEncode( int iHour, int iMinutes, int iSeconds, int iMSec ) } void hb_timeStampDecode( LONG lMillisec, int * piHour, int * piMinutes, - int * piSeconds, int * piMSec ) + int * piSeconds, int * piMSec ) { HB_TRACE(HB_TR_DEBUG, ("hb_timeStampDecode(%ld, %p, %p, %p, %p)", lMillisec, piHour, piMinutes, piSeconds, piMSec)); @@ -384,7 +384,7 @@ char * hb_timeStampStr( char * szTime, LONG lMillisec ) hb_timeStampDecode( lMillisec, &iHour, &iMinutes, &iSeconds, &iMSec ); hb_snprintf( szTime, 13, "%02d:%02d:%02d.%03d", - iHour, iMinutes, iSeconds, iMSec ); + iHour, iMinutes, iSeconds, iMSec ); szTime[ 12 ] = '\0'; return szTime; @@ -409,7 +409,7 @@ char * hb_dateTimeStampStr( char * szDateTime, LONG lJulian, LONG lMillisec ) } void hb_timeStrGet( const char * szTime, int * piHour, int * piMinutes, - int * piSeconds, int * piMSec ) + int * piSeconds, int * piMSec ) { int iHour, iMinutes, iSeconds, iMSec; diff --git a/harbour/source/rtl/errorint.c b/harbour/source/rtl/errorint.c index 77a5a68c09..9dd59a2b11 100644 --- a/harbour/source/rtl/errorint.c +++ b/harbour/source/rtl/errorint.c @@ -93,7 +93,7 @@ void hb_errInternalRaw( ULONG ulIntCode, const char * szText, const char * szPar hb_dateToday( &iYear, &iMonth, &iDay ); hb_dateTimeStr( szTime ); - fprintf( hLog, HB_I_("Application Internal Error - %s\n"), hb_cmdargARGV()[0] ); + fprintf( hLog, HB_I_("Application Internal Error - %s\n"), hb_cmdargARGVN( 0 ) ); fprintf( hLog, HB_I_("Terminated at: %04d.%02d.%02d %s\n"), iYear, iMonth, iDay, szTime ); if( *hb_setGetCPtr( HB_SET_HBOUTLOGINFO ) ) fprintf( hLog, HB_I_("Info: %s\n"), hb_setGetCPtr( HB_SET_HBOUTLOGINFO ) ); diff --git a/harbour/source/rtl/filesys.c b/harbour/source/rtl/filesys.c index e1c9be2f47..81be36fbbd 100644 --- a/harbour/source/rtl/filesys.c +++ b/harbour/source/rtl/filesys.c @@ -2672,11 +2672,10 @@ USHORT hb_fsCurDirBuff( USHORT uiDrive, BYTE * pbyBuffer, ULONG ulLen ) BOOL fFree; BYTE * pbyResult = hb_osDecode( pbyBuffer, &fFree ); - if( fFree ) - { + if( pbyResult != pbyBuffer ) hb_strncpy( ( char * ) pbyBuffer, ( char * ) pbyResult, ulLen - 1 ); + if( fFree ) hb_xfree( pbyResult ); - } } } @@ -2882,7 +2881,7 @@ BYTE * hb_fsExtName( BYTE * pFilename, BYTE * pDefExt, { pFilepath->szPath = szDefault; hb_fsFNameMerge( ( char * ) szPath, pFilepath ); - fIsFile = hb_fsFile( szPath ); + fIsFile = hb_fsFileExists( ( const char * ) szPath ); } if( !fIsFile && ( uiExFlags & ( FXO_TRUNCATE | FXO_APPEND | FXO_UNIQUE ) ) == 0 && @@ -2893,7 +2892,7 @@ BYTE * hb_fsExtName( BYTE * pFilename, BYTE * pDefExt, { pFilepath->szPath = pNextPath->szPath; hb_fsFNameMerge( ( char * ) szPath, pFilepath ); - fIsFile = hb_fsFile( szPath ); + fIsFile = hb_fsFileExists( ( const char * ) szPath ); pNextPath = pNextPath->pNext; } } @@ -2912,7 +2911,7 @@ BYTE * hb_fsExtName( BYTE * pFilename, BYTE * pDefExt, { pFilepath->szPath = pNextPath->szPath; hb_fsFNameMerge( ( char * ) szPath, pFilepath ); - fIsFile = hb_fsFile( szPath ); + fIsFile = hb_fsFileExists( ( const char * ) szPath ); pNextPath = pNextPath->pNext; } hb_fsFreeSearchPath( pSearchPath ); @@ -3216,65 +3215,25 @@ BYTE * hb_fsNameConv( BYTE * szFileName, BOOL * pfFree ) /* NOTE: pbyBuffer must be _POSIX_PATH_MAX + 1 long. */ void hb_fsBaseDirBuff( BYTE * pbyBuffer ) { -#if defined( HB_OS_UNIX_COMPATIBLE ) + const char * szBaseName = hb_cmdargARGVN( 0 ); + + if( szBaseName ) { - /* Assemble the full path of the program by taking the - current dir and appending the name of the program, - as specified on the command-line. - HB_OS_UNIX_COMPATIBLE might be too rough to decide - for this method, pls test on other platforms and refine. - [vszakats] */ - - char byCurDir[ _POSIX_PATH_MAX + 1 ]; - char byBinDir[ _POSIX_PATH_MAX + 1 ]; - int nBinDirOffset = 0; - - PHB_FNAME pFName = hb_fsFNameSplit( hb_cmdargARGV()[ 0 ] ); + PHB_FNAME pFName = hb_fsFNameSplit( szBaseName ); + BYTE * pbyResult; + BOOL fFree; pFName->szName = NULL; pFName->szExtension = NULL; - - hb_fsFNameMerge( ( char * ) byBinDir, pFName ); - hb_xfree( pFName ); - - /* Skip 'current dir' if present, and replace with cwd. */ - if( byBinDir[ 0 ] == '.' && byBinDir[ 1 ] == HB_OS_PATH_DELIM_CHR ) - { - nBinDirOffset += 2; - - hb_fsCurDirBuff( 0, ( BYTE * ) byCurDir, sizeof( byCurDir ) ); - - hb_strncpy( pbyBuffer, HB_OS_PATH_DELIM_CHR_STRING, _POSIX_PATH_MAX ); - if( byCurDir[ 0 ] != '\0' ) - { - hb_strncat( pbyBuffer, byCurDir, _POSIX_PATH_MAX ); - hb_strncat( pbyBuffer, HB_OS_PATH_DELIM_CHR_STRING, _POSIX_PATH_MAX ); - } - } - hb_strncat( pbyBuffer, byBinDir + nBinDirOffset, _POSIX_PATH_MAX ); - } -#else - { - PHB_FNAME pFName = hb_fsFNameSplit( hb_cmdargARGV()[ 0 ] ); - - pFName->szName = NULL; - pFName->szExtension = NULL; - hb_fsFNameMerge( ( char * ) pbyBuffer, pFName ); hb_xfree( pFName ); - } -#endif - /* Convert from OS codepage */ - { - BOOL fFree; - BYTE * pbyResult = hb_osDecode( pbyBuffer, &fFree ); - - if( fFree ) - { + /* Convert from OS codepage */ + pbyResult = hb_osDecode( pbyBuffer, &fFree ); + if( pbyResult != pbyBuffer ) hb_strncpy( ( char * ) pbyBuffer, ( char * ) pbyResult, _POSIX_PATH_MAX ); + if( fFree ) hb_xfree( pbyResult ); - } } } diff --git a/harbour/source/rtl/philes.c b/harbour/source/rtl/philes.c index 5911327088..8d36582053 100644 --- a/harbour/source/rtl/philes.c +++ b/harbour/source/rtl/philes.c @@ -289,50 +289,21 @@ HB_FUNC( CURDIR ) HB_FUNC( HB_PROGNAME ) { - char byBuffer[ _POSIX_PATH_MAX + 1 ]; + const char * szBaseName = hb_cmdargARGVN( 0 ); -#if defined( HB_OS_UNIX_COMPATIBLE ) - { - /* Assemble the full path of the program by taking the - current dir and appending the name of the program, - as specified on the command-line. - HB_OS_UNIX_COMPATIBLE might be too rough to decide - for this method, pls test on other platforms and refine. - [vszakats] */ - - char byCurDir[ _POSIX_PATH_MAX + 1 ]; - char * pbyARGV0 = hb_cmdargARGV()[ 0 ]; - - /* Skip 'current dir' if present, and replace with cwd. */ - if( pbyARGV0[ 0 ] == '.' && pbyARGV0[ 1 ] == HB_OS_PATH_DELIM_CHR ) - { - pbyARGV0 += 2; - - hb_fsCurDirBuff( 0, ( BYTE * ) byCurDir, sizeof( byCurDir ) ); - - hb_strncpy( byBuffer, HB_OS_PATH_DELIM_CHR_STRING, sizeof( byBuffer ) - 1 ); - if( byCurDir[ 0 ] != '\0' ) - { - hb_strncat( byBuffer, byCurDir, sizeof( byBuffer ) - 1 ); - hb_strncat( byBuffer, HB_OS_PATH_DELIM_CHR_STRING, sizeof( byBuffer ) - 1 ); - } - } - hb_strncat( byBuffer, pbyARGV0, sizeof( byBuffer ) - 1 ); - } -#else - hb_strncpy( byBuffer, hb_cmdargARGV()[ 0 ], sizeof( byBuffer ) - 1 ); -#endif - - /* Convert from OS codepage */ + if( szBaseName ) { + /* Convert from OS codepage */ BOOL fFree; - char * pbyResult = ( char * ) hb_osDecode( ( BYTE * ) byBuffer, &fFree ); + char * pbyResult = ( char * ) hb_osDecode( ( BYTE * ) szBaseName, &fFree ); if( fFree ) hb_retc_buffer( pbyResult ); else - hb_retc( byBuffer ); + hb_retc( pbyResult ); } + else + hb_retc( NULL ); } HB_FUNC( HB_DIRBASE ) diff --git a/harbour/source/vm/cmdarg.c b/harbour/source/vm/cmdarg.c index 52d5479923..9e865051eb 100644 --- a/harbour/source/vm/cmdarg.c +++ b/harbour/source/vm/cmdarg.c @@ -55,6 +55,7 @@ #include "hbvmopt.h" #include "hbapi.h" #include "hbapiitm.h" +#include "hbapifs.h" #include "hbvm.h" #include "hbmemory.ch" #include "hbstack.h" @@ -64,8 +65,9 @@ static int s_argc = 0; static char ** s_argv = NULL; -#if defined( HB_OS_WIN ) - +#if !defined( HB_OS_WIN ) +static char s_szAppName[ _POSIX_PATH_MAX + 1 ]; +#else static char s_szAppName[ MAX_PATH ]; static TCHAR s_lpAppName[ MAX_PATH ]; @@ -114,7 +116,75 @@ void hb_cmdargInit( int argc, char * argv[] ) HB_TCHAR_GETFROM( s_szAppName, s_lpAppName, MAX_PATH ); s_argv[ 0 ] = s_szAppName; } +#else + /* NOTE: try to create absolute path from s_argv[ 0 ] if necessary */ + { + PHB_FNAME pFName = hb_fsFNameSplit( s_argv[ 0 ] ); + BOOL fInPath = FALSE; + if( !pFName->szPath ) + { + char * pszPATH = hb_getenv( "PATH" ); + + if( pszPATH && *pszPATH ) + { + HB_PATHNAMES * pSearchPath = NULL, * pNextPath; + hb_fsAddSearchPath( pszPATH, &pSearchPath ); + pNextPath = pSearchPath; + while( pNextPath ) + { + pFName->szPath = pNextPath->szPath; + hb_fsFNameMerge( s_szAppName, pFName ); + if( hb_fsFileExists( s_szAppName ) ) + { + /* even if the file is located using PATH then it does + * not mean we will have absolute path here. It's not + * good idea but PATH envvar can also contain relative + * directories, f.e. "." or "bin" so we should add + * current directory if necessary in code below. + */ + hb_xfree( pFName ); + pFName = hb_fsFNameSplit( s_szAppName ); + fInPath = TRUE; + break; + } + pNextPath = pNextPath->pNext; + } + hb_fsFreeSearchPath( pSearchPath ); + if( !fInPath ) + pFName->szPath = NULL; + } + if( pszPATH ) + hb_xfree( pszPATH ); + } + if( pFName->szPath ) + { +#if defined(HB_OS_HAS_DRIVE_LETTER) + if( pFName->szPath[ 0 ] != HB_OS_PATH_DELIM_CHR && !pFName->szDrive ) +#else + if( pFName->szPath[ 0 ] != HB_OS_PATH_DELIM_CHR ) +#endif + { + if( pFName->szPath[ 0 ] == '.' && + pFName->szPath[ 1 ] == HB_OS_PATH_DELIM_CHR ) + pFName->szPath += 2; + s_szAppName[ 0 ] = HB_OS_PATH_DELIM_CHR; + hb_fsCurDirBuff( 0, ( BYTE * ) ( s_szAppName + 1 ), _POSIX_PATH_MAX ); + if( s_szAppName[ 1 ] != 0 ) + { + hb_strncat( s_szAppName, HB_OS_PATH_DELIM_CHR_STRING, _POSIX_PATH_MAX ); + hb_strncat( s_szAppName, pFName->szPath, _POSIX_PATH_MAX ); + pFName->szPath = hb_strdup( s_szAppName ); + hb_fsFNameMerge( s_szAppName, pFName ); + hb_xfree( ( void * ) pFName->szPath ); + s_argv[ 0 ] = s_szAppName; + } + } + else if( fInPath ) + s_argv[ 0 ] = s_szAppName; + } + hb_xfree( pFName ); + } #endif } @@ -128,6 +198,11 @@ char ** hb_cmdargARGV( void ) return s_argv; } +const char * hb_cmdargARGVN( int argc ) +{ + return argc >= 0 && argc < s_argc ? s_argv[ argc ] : NULL; +} + BOOL hb_cmdargIsInternal( const char * szArg, int * piLen ) { HB_TRACE(HB_TR_DEBUG, ("hb_cmdargIsInternal(%s, %p)", szArg, piLen));