diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 0f895644c2..f5b7d7f4fc 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -16,6 +16,33 @@ The license applies to all entries newer than 2009-04-28. */ +2010-06-23 12:47 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/include/hbextern.ch + * harbour/src/vm/runner.c + + added new PRG function + HB_HRBSIGNATURE() -> + which returns HRB file signature + + added internal function hb_hrbCheckSig() to keep HRB file + signature checking in one place + + * harbour/include/hbextern.ch + * harbour/src/vm/cmdarg.c + + added new PRG function + HB_ARGSHIFT( [] ) -> NIL + which updates HB_ARG*() parameter list removing the 1-st one + and replacing it by others. If is .T. then first + non internal parameter is moved to hb_argv(0) (hb_progname()) + and all next are shifted. + + * harbour/utils/hbrun/hbrun.prg + + when extension does not allow to recognize file type then check + passed file signature. If it's HRB file then execute directly + otherwise use it as PRG script. + This modification allows to use any names (except the ones using + known for HBRUN extensions like .hrb amd .dbf) as PRG script names. + + Call HB_ARGSHIFT(.T.) to strip HBRUN executable file name from + parameter list when PRG script or HRB file is executed + 2010-06-23 12:01 UTC+0200 Viktor Szakats (harbour.01 syenar.hu) * include/hbdefs.h + Added new abstract type: HB_USIZ diff --git a/harbour/include/hbextern.ch b/harbour/include/hbextern.ch index 32da8a5485..37b0e3faec 100644 --- a/harbour/include/hbextern.ch +++ b/harbour/include/hbextern.ch @@ -795,6 +795,7 @@ EXTERNAL HB_ARGC EXTERNAL HB_ARGCHECK EXTERNAL HB_ARGSTRING EXTERNAL HB_ARGV +EXTERNAL HB_ARGSHIFT EXTERNAL HB_CMDLINE EXTERNAL HB_COLORINDEX EXTERNAL HB_VERSION @@ -1004,6 +1005,7 @@ EXTERNAL HB_HRBDO EXTERNAL HB_HRBLOAD EXTERNAL HB_HRBUNLOAD EXTERNAL HB_HRBGETFUNSYM +EXTERNAL HB_HRBSIGNATURE EXTERNAL HB_LIBLOAD EXTERNAL HB_LIBFREE diff --git a/harbour/src/vm/cmdarg.c b/harbour/src/vm/cmdarg.c index 03e6d0464f..909837f009 100644 --- a/harbour/src/vm/cmdarg.c +++ b/harbour/src/vm/cmdarg.c @@ -451,6 +451,33 @@ HB_FUNC( HB_ARGV ) hb_retc( ( argc >= 0 && argc < s_argc ) ? s_argv[ argc ] : NULL ); } +HB_FUNC( HB_ARGSHIFT ) +{ + int iArg = 1; + + if( hb_parl( 1 ) ) + { + while( iArg < s_argc ) + { + if( !hb_cmdargIsInternal( s_argv[ iArg ], NULL ) ) + { + s_argv[ 0 ] = s_argv[ iArg ]; + break; + } + ++iArg; + } + } + if( iArg < s_argc ) + { + --s_argc; + while( iArg < s_argc ) + { + s_argv[ iArg ] = s_argv[ iArg + 1 ]; + ++iArg; + } + } +} + HB_FUNC( HB_CMDLINE ) { char** argv = hb_cmdargARGV(); diff --git a/harbour/src/vm/runner.c b/harbour/src/vm/runner.c index cbbde9d52d..adc3685c46 100644 --- a/harbour/src/vm/runner.c +++ b/harbour/src/vm/runner.c @@ -90,7 +90,7 @@ typedef struct PHB_SYMBOLS pModuleSymbols; } HRB_BODY, * PHRB_BODY; -static const HB_BYTE s_szHead[ 4 ] = { 192, 'H', 'R', 'B' }; +static const char s_szHead[ 4 ] = { '\300', 'H', 'R', 'B' }; #define SYM_NOLINK 0 /* symbol does not have to be linked */ @@ -99,17 +99,27 @@ static const HB_BYTE s_szHead[ 4 ] = { 192, 'H', 'R', 'B' }; #define SYM_DEFERRED 3 /* lately bound function */ #define SYM_NOT_FOUND 0xFFFFFFFFUL /* Symbol not found. */ +static HB_SIZE hb_hrbCheckSig( const char * szBody, HB_SIZE ulBodySize ) +{ + return ( ulBodySize > sizeof( s_szHead ) && + memcmp( s_szHead, szBody, sizeof( s_szHead ) ) == 0 ) ? + sizeof( s_szHead ) : 0; +} + static int hb_hrbReadHead( const char * szBody, HB_SIZE ulBodySize, HB_SIZE * pulBodyOffset ) { const char * pVersion; + HB_SIZE nSigSize; HB_TRACE(HB_TR_DEBUG, ("hb_hrbReadHead(%p,%" HB_PFS "u,%p)", szBody, ulBodySize, pulBodyOffset )); - if( ulBodySize < 6 || memcmp( s_szHead, szBody, 4 ) ) + nSigSize = hb_hrbCheckSig( szBody, ulBodySize ); + + if( nSigSize == 0 || ulBodySize - nSigSize < 2 ) return 0; - pVersion = szBody + 4; - *pulBodyOffset += 6; + pVersion = szBody + nSigSize; + *pulBodyOffset += nSigSize + 2; return HB_PCODE_MKSHORT( pVersion ); } @@ -712,7 +722,7 @@ HB_FUNC( HB_HRBRUN ) const char * fileOrBody = hb_parc( nParam ); PHRB_BODY pHrbBody; - if( ulLen > 4 && memcmp( s_szHead, fileOrBody, 4 ) == 0 ) + if( hb_hrbCheckSig( fileOrBody, ulLen ) != 0 ) pHrbBody = hb_hrbLoad( fileOrBody, ulLen, usMode ); else pHrbBody = hb_hrbLoadFromFile( fileOrBody, usMode ); @@ -762,7 +772,7 @@ HB_FUNC( HB_HRBLOAD ) const char * fileOrBody = hb_parc( nParam ); PHRB_BODY pHrbBody; - if( ulLen > 4 && memcmp( s_szHead, fileOrBody, 4 ) == 0 ) + if( hb_hrbCheckSig( fileOrBody, ulLen ) != 0 ) pHrbBody = hb_hrbLoad( fileOrBody, ulLen, usMode ); else pHrbBody = hb_hrbLoadFromFile( fileOrBody, usMode ); @@ -859,3 +869,8 @@ HB_FUNC( HB_HRBGETFUNSYM ) else hb_errRT_BASE( EG_ARG, 6106, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } + +HB_FUNC( HB_HRBSIGNATURE ) +{ + hb_retclen( s_szHead, sizeof( s_szHead ) ); +} diff --git a/harbour/utils/hbrun/hbrun.prg b/harbour/utils/hbrun/hbrun.prg index d37ee081c6..4a0dcbd75b 100644 --- a/harbour/utils/hbrun/hbrun.prg +++ b/harbour/utils/hbrun/hbrun.prg @@ -53,6 +53,7 @@ #include "common.ch" #include "inkey.ch" #include "setcurs.ch" +#include "fileio.ch" /* NOTE: use hbextern library instead of #include "hbextern.ch" * in dynamic builds it will greatly reduce the size because @@ -106,19 +107,30 @@ PROCEDURE _APPMAIN( cFile, ... ) EXIT OTHERWISE hb_FNameSplit( cFile, NIL, NIL, @cExt ) - IF Lower( cExt ) == ".prg" - cFile := HB_COMPILEBUF( HB_ARGV( 0 ), "-n2", "-w", "-es2", "-q0", ; - s_aIncDir, cFile ) - IF cFile == NIL - ERRORLEVEL( 1 ) - ELSE + cExt := lower( cExt ) + SWITCH cExt + CASE ".prg" + CASE ".hrb" + CASE ".dbf" + EXIT + OTHERWISE + cExt := HB_DotFileSig( cFile ) + ENDSWITCH + SWITCH cExt + CASE ".dbf" + HB_DotPrompt( "USE " + cFile ) + EXIT + CASE ".prg" + cFile := HB_COMPILEBUF( HB_ARGV( 0 ), "-n2", "-w", "-es2", "-q0", ; + s_aIncDir, cFile ) + IF cFile == NIL + ERRORLEVEL( 1 ) + ENDIF + OTHERWISE + hb_argShift( .T. ) hb_hrbRun( cFile, ... ) - ENDIF - ELSEIF Lower( cExt ) == ".dbf" - HB_DotPrompt( "USE " + cFile ) - ELSE - hb_hrbRun( cFile, ... ) - ENDIF + EXIT + ENDSWITCH ENDSWITCH ELSE HB_DotPrompt() @@ -126,6 +138,24 @@ PROCEDURE _APPMAIN( cFile, ... ) RETURN +STATIC FUNCTION HB_DotFileSig( cFile ) + LOCAL hFile + LOCAL cBuff, cSig, cExt + + cExt := ".prg" + hFile := FOpen( cFile, FO_READ ) + IF hFile != F_ERROR + cSig := hb_hrbSignature() + cBuff := Space( Len( cSig ) ) + FRead( hFile, @cBuff, Len( cSig ) ) + FClose( hFile ) + IF cBuff == cSig + cExt := ".hrb" + ENDIF + ENDIF + + RETURN cExt + STATIC PROCEDURE HB_DotPrompt( cCommand ) LOCAL GetList LOCAL cLine