From 46e9900a91b10104402c0dec784e442482f8a6b1 Mon Sep 17 00:00:00 2001 From: Przemyslaw Czerpak Date: Wed, 23 Jun 2010 10:47:41 +0000 Subject: [PATCH] 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 --- harbour/ChangeLog | 27 ++++++++++++++++++ harbour/include/hbextern.ch | 2 ++ harbour/src/vm/cmdarg.c | 27 ++++++++++++++++++ harbour/src/vm/runner.c | 27 ++++++++++++++---- harbour/utils/hbrun/hbrun.prg | 54 +++++++++++++++++++++++++++-------- 5 files changed, 119 insertions(+), 18 deletions(-) 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