From d484e5e22e00fb52fc6462a36f85b9a9201b5383 Mon Sep 17 00:00:00 2001 From: Eddie Runia Date: Wed, 19 May 1999 11:55:04 +0000 Subject: [PATCH] See change log --- harbour/ChangeLog | 12 ++ harbour/source/compiler/harbour.y | 7 +- harbour/tests/broken/run_exp.h | 78 ------------ harbour/tests/working/readhrb.lnk | 5 + harbour/tests/working/readhrb.prg | 102 +++++++++++++++ harbour/tests/working/run_exp.h | 118 ++++++++++++++++++ harbour/tests/{broken => working}/runner.c | 97 ++++++++++---- harbour/tests/working/spawn.prg | 11 ++ .../{broken/hrb.bat => working/stub.bat} | 2 +- 9 files changed, 328 insertions(+), 104 deletions(-) delete mode 100644 harbour/tests/broken/run_exp.h create mode 100644 harbour/tests/working/readhrb.lnk create mode 100644 harbour/tests/working/readhrb.prg create mode 100644 harbour/tests/working/run_exp.h rename harbour/tests/{broken => working}/runner.c (78%) create mode 100644 harbour/tests/working/spawn.prg rename harbour/tests/{broken/hrb.bat => working/stub.bat} (61%) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index fdd47a720e..1e2b1eae53 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,15 @@ +19990519-12:50 CET Eddie Runia + * source/compiler/harbour.y + Some clean up + * source/tests/broken/runner.c | run_exp.h | stub.bat + removed + * source/tests/working/runner.c | run_exp.h | stub.bat + added runner code + * source/tests/working/spawn.prg + spawn example program + * source/tests/working/readhrb.prg + readhrb.lnk + Clipper program to read .HRB files + 19990518-23:15 David G. Holm * makefile.b31 - Put all common BCC options in c_opt macro to make it easy to switch to diff --git a/harbour/source/compiler/harbour.y b/harbour/source/compiler/harbour.y index 7f8211e3a7..cfae332755 100644 --- a/harbour/source/compiler/harbour.y +++ b/harbour/source/compiler/harbour.y @@ -3363,7 +3363,7 @@ char * strupr( char * p ) void GenPortObj( char *szFileName, char *szName ) { - PFUNCTION pFunc = functions.pFirst, pFTemp; + PFUNCTION pFunc = functions.pFirst; PCOMSYMBOL pSym = symbols.pFirst; WORD w, wLen, wSym, wVar; LONG lPCodePos; @@ -3372,6 +3372,7 @@ void GenPortObj( char *szFileName, char *szName ) char chr; FILE * yyc; /* file handle for C output */ + szName = szName; if( ! ( yyc = fopen( szFileName, "wb" ) ) ) { printf( "Error opening file %s\n", szFileName ); @@ -3412,13 +3413,13 @@ void GenPortObj( char *szFileName, char *szName ) /* specify the function address if it is a defined function or a external called function */ - if( ( pFTemp = GetFunction( pSym->szName ) ) ) /* is it a defined function ? */ + if( GetFunction( pSym->szName ) ) /* is it a defined function ? */ { fputc( SYM_FUNC, yyc ); } else { - if( ( pFTemp = GetFuncall( pSym->szName ) ) ) + if( GetFuncall( pSym->szName ) ) { fputc( SYM_EXTERN, yyc ); } diff --git a/harbour/tests/broken/run_exp.h b/harbour/tests/broken/run_exp.h deleted file mode 100644 index 93ee78af83..0000000000 --- a/harbour/tests/broken/run_exp.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * - * This file contains the exportable functions available to the Harbour program - * - * Currently being discussed in 'Static initializers' - * - * If the discussion has finished, it can be removed from here. - * - * Currently containing : - * - * Arrays - * Console - * HVM - * - */ -HARBOUR ARRAY(); -HARBOUR AADD(); -HARBOUR ASIZE(); -HARBOUR ATAIL(); -HARBOUR AINS(); -HARBOUR ADEL(); -HARBOUR AFILL(); -HARBOUR ASCAN(); -HARBOUR AEVAL(); -HARBOUR ACOPY(); -HARBOUR ACLONE(); -HARBOUR __ACCEPT(); -HARBOUR OUTSTD(); -HARBOUR QQOUT(); -HARBOUR QOUT(); -HARBOUR ERRORSYS(); -HARBOUR ERRORNEW(); -HARBOUR EVAL(); -HARBOUR VALTYPE(); -HARBOUR UPPER(); -HARBOUR VAL(); -HARBOUR STRDUMP(); -HARBOUR TRIM(); -HARBOUR LTRIM(); -HARBOUR RTRIM(); -HARBOUR CHR(); - -/* Same story. - - All the function pointers of the internal functions - Including Runner itself, since the first symbol gets executed by Harbour ;-) -*/ -static SYMBOL symbols[] = { -{ "Runner", FS_PUBLIC, Runner , 0 }, -{ "ARRAY", FS_PUBLIC, ARRAY , 0 }, -{ "AADD", FS_PUBLIC, AADD , 0 }, -{ "ASIZE", FS_PUBLIC, ASIZE , 0 }, -{ "ATAIL", FS_PUBLIC, ATAIL , 0 }, -{ "AINS", FS_PUBLIC, AINS , 0 }, -{ "ADEL", FS_PUBLIC, ADEL , 0 }, -{ "AFILL", FS_PUBLIC, AFILL , 0 }, -{ "ASCAN", FS_PUBLIC, ASCAN , 0 }, -{ "AEVAL", FS_PUBLIC, AEVAL , 0 }, -{ "ACOPY", FS_PUBLIC, ACOPY , 0 }, -{ "ACLONE", FS_PUBLIC, ACLONE , 0 }, -{ "__ACCEPT", FS_PUBLIC, __ACCEPT, 0 }, -{ "OUTSTD", FS_PUBLIC, OUTSTD , 0 }, -{ "QQOUT", FS_PUBLIC, QQOUT , 0 }, -{ "QOUT", FS_PUBLIC, QOUT , 0 }, -{ "ERRORSYS", FS_PUBLIC, ERRORSYS, 0 }, -{ "ERRORNEW", FS_PUBLIC, ERRORNEW, 0 }, -{ "EVAL", FS_PUBLIC, EVAL , 0 }, -{ "VALTYPE", FS_PUBLIC, VALTYPE , 0 }, -{ "UPPER", FS_PUBLIC, UPPER , 0 }, -{ "STRDUMP", FS_PUBLIC, STRDUMP , 0 }, -{ "TRIM", FS_PUBLIC, TRIM , 0 }, -{ "LTRIM", FS_PUBLIC, LTRIM , 0 }, -{ "RTRIM", FS_PUBLIC, RTRIM , 0 }, -{ "CHR", FS_PUBLIC, CHR , 0 }, -{ "VAL", FS_PUBLIC, VAL , 0 } -}; - - diff --git a/harbour/tests/working/readhrb.lnk b/harbour/tests/working/readhrb.lnk new file mode 100644 index 0000000000..83d353f8d8 --- /dev/null +++ b/harbour/tests/working/readhrb.lnk @@ -0,0 +1,5 @@ +OUTPUT READHRB.exe + + FILE READHRB.OBJ + LIB BLXCLP52, BLXRATEX + diff --git a/harbour/tests/working/readhrb.prg b/harbour/tests/working/readhrb.prg new file mode 100644 index 0000000000..b2879e7dbe --- /dev/null +++ b/harbour/tests/working/readhrb.prg @@ -0,0 +1,102 @@ +/* + ReadHRB + + This program will read the .HRB file and shows its contents + + ReadHRB {No .HRB extension please} +*/ + +function Main( cFrom ) + + local hFile + local cBlock := " " + local n, m + local nVal + local nSymbols + local nFuncs + local cMode := "SYMBOL" + local cScope + local nLenCount + + SET EXACT ON + SET DATE TO BRITISH + SET ALTERNATE TO readhrb.out + SET ALTERNATE ON + + if cFrom == NIL + cFrom := "hello.hrb" + else + cFrom := cFrom + ".hrb" + endif + + hFile := fOpen( cFrom ) + + cBlock := fReadStr( hFile, 4 ) + nSymbols := asc(substr(cBlock,1,1)) +; + asc(substr(cBlock,2,1)) *256 +; + asc(substr(cBlock,3,1)) *65536 +; + asc(substr(cBlock,4,1)) *16777216 + for n := 1 to nSymbols + cBlock := fReadStr( hFile, 1 ) + do while asc( cBlock ) != 0 + QQOut( cBlock ) + cBlock := fReadStr( hFile, 1 ) + enddo + cScope := fReadStr( hFile, 1 ) + QQOut(" Scope ", Hex2Val(asc(cScope))) + cScope := fReadStr( hFile, 1 ) + QQOut(" Type ", { "NOLINK", "FUNC", "EXTERN" }[ asc(cScope)+1 ] ) + QOut() + next n + + cBlock := fReadStr( hFile, 4 ) + nFuncs := asc(substr(cBlock,1,1)) +; + asc(substr(cBlock,2,1)) *256 +; + asc(substr(cBlock,3,1)) *65536 +; + asc(substr(cBlock,4,1)) *16777216 + for n := 1 to nFuncs + QOut() + cBlock := fReadStr( hFile, 1 ) + do while asc( cBlock ) != 0 + QQOut( cBlock ) + cBlock := fReadStr( hFile, 1 ) + enddo + QOut( "Len = " ) + cBlock := fReadStr( hFile, 4 ) + + nLenCount := asc(substr(cBlock,1,1)) +; + asc(substr(cBlock,2,1)) *256 +; + asc(substr(cBlock,3,1)) *65536 +; + asc(substr(cBlock,4,1)) *16777216 +1 + QQOut( str(nLenCount) ) + QOut() + + for m:=1 to nLenCount + cBlock := fReadStr( hFile, 1 ) + nVal := asc( cBlock ) + QQOut( Hex2Val( nVal ) ) + if nVal > 32 .and. nVal < 128 + QQOut( "("+cBlock+")" ) + endif + if m != nLenCount + QQOut(",") + endif + next m + next n + + fClose( cFrom ) + + SET ALTERNATE OFF + CLOSE ALTERNATE +return nil + + +function Hex2Val( nVal ) + +return HexDigit( int(nVal / 16) ) + HexDigit( int(nVal % 16) ) + +function HexDigit( nDigit ) + +return if(nDigit>=10, chr( 55 + nDigit ), chr( 48 + nDigit ) ) + + diff --git a/harbour/tests/working/run_exp.h b/harbour/tests/working/run_exp.h new file mode 100644 index 0000000000..e0f6b9701a --- /dev/null +++ b/harbour/tests/working/run_exp.h @@ -0,0 +1,118 @@ +/* + * + * This file contains the exportable functions available to the Harbour program + * + * Currently being discussed in 'Static initializers' + * + * If the discussion has finished, it can be removed from here. + * + * Currently containing : + * + * Arrays + * ASort + * Classes + * Console + * HVM + * + */ +HARBOUR ARRAY(); +HARBOUR AADD(); +HARBOUR ASIZE(); +HARBOUR ATAIL(); +HARBOUR AINS(); +HARBOUR ADEL(); +HARBOUR AFILL(); +HARBOUR ASCAN(); +HARBOUR AEVAL(); +HARBOUR ACOPY(); +HARBOUR ACLONE(); +HARBOUR __ACCEPT(); +HARBOUR OUTSTD(); +HARBOUR QQOUT(); +HARBOUR QOUT(); +HARBOUR ERRORSYS(); +HARBOUR ERRORNEW(); +HARBOUR EVAL(); +HARBOUR VALTYPE(); +HARBOUR UPPER(); +HARBOUR VAL(); +HARBOUR ASORT(); +HARBOUR CLASSCREATE(); +HARBOUR CLASSADD(); +HARBOUR CLASSNAME(); +HARBOUR CLASSINSTANCE(); +HARBOUR ISMESSAGE(); +HARBOUR OSEND(); +HARBOUR CLASSMOD(); +HARBOUR CLASSDEL(); +HARBOUR OCLONE(); +HARBOUR CTOD(); +HARBOUR DTOC(); +HARBOUR DTOS(); +HARBOUR STOD(); +HARBOUR DAY(); +HARBOUR MONTH(); +HARBOUR YEAR(); +HARBOUR TIME(); +HARBOUR HB_SETCENTURY(); +HARBOUR SET(); +HARBOUR LTRIM(); +HARBOUR RTRIM(); +HARBOUR ALLTRIM(); +HARBOUR TRIM(); + +/* Same story. + + All the function pointers of the internal functions + Including Runner itself, since the first symbol gets executed by Harbour ;-) +*/ + +static SYMBOL symbols[] = { +{ "HB_RUN", FS_PUBLIC, HB_RUN , 0 }, +{ "ARRAY", FS_PUBLIC, ARRAY , 0 }, +{ "AADD", FS_PUBLIC, AADD , 0 }, +{ "ASIZE", FS_PUBLIC, ASIZE , 0 }, +{ "ATAIL", FS_PUBLIC, ATAIL , 0 }, +{ "AINS", FS_PUBLIC, AINS , 0 }, +{ "ADEL", FS_PUBLIC, ADEL , 0 }, +{ "AFILL", FS_PUBLIC, AFILL , 0 }, +{ "ASCAN", FS_PUBLIC, ASCAN , 0 }, +{ "AEVAL", FS_PUBLIC, AEVAL , 0 }, +{ "ACOPY", FS_PUBLIC, ACOPY , 0 }, +{ "ACLONE", FS_PUBLIC, ACLONE , 0 }, +{ "__ACCEPT", FS_PUBLIC, __ACCEPT , 0 }, +{ "OUTSTD", FS_PUBLIC, OUTSTD , 0 }, +{ "QQOUT", FS_PUBLIC, QQOUT , 0 }, +{ "QOUT", FS_PUBLIC, QOUT , 0 }, +{ "ERRORSYS", FS_PUBLIC, ERRORSYS , 0 }, +{ "ERRORNEW", FS_PUBLIC, ERRORNEW , 0 }, +{ "EVAL", FS_PUBLIC, EVAL , 0 }, +{ "VALTYPE", FS_PUBLIC, VALTYPE , 0 }, +{ "UPPER", FS_PUBLIC, UPPER , 0 }, +{ "VAL", FS_PUBLIC, VAL , 0 }, +{ "ASORT", FS_PUBLIC, ASORT , 0 }, +{ "CLASSCREATE", FS_PUBLIC, CLASSCREATE , 0 }, +{ "CLASSADD", FS_PUBLIC, CLASSADD , 0 }, +{ "CLASSNAME", FS_PUBLIC, CLASSNAME , 0 }, +{ "CLASSINSTANCE", FS_PUBLIC, CLASSINSTANCE , 0 }, +{ "ISMESSAGE", FS_PUBLIC, ISMESSAGE , 0 }, +{ "OSEND", FS_PUBLIC, OSEND , 0 }, +{ "CLASSMOD", FS_PUBLIC, CLASSMOD , 0 }, +{ "CLASSDEL", FS_PUBLIC, CLASSDEL , 0 }, +{ "OCLONE", FS_PUBLIC, OCLONE , 0 }, +{ "CTOD", FS_PUBLIC, CTOD , 0 }, +{ "DTOC", FS_PUBLIC, DTOC , 0 }, +{ "DTOS", FS_PUBLIC, DTOS , 0 }, +{ "STOD", FS_PUBLIC, STOD , 0 }, +{ "DAY", FS_PUBLIC, DAY , 0 }, +{ "MONTH", FS_PUBLIC, MONTH , 0 }, +{ "YEAR", FS_PUBLIC, YEAR , 0 }, +{ "TIME", FS_PUBLIC, TIME , 0 }, +{ "HB_SETCENTURY", FS_PUBLIC, HB_SETCENTURY , 0 }, +{ "SET", FS_PUBLIC, SET , 0 }, +{ "TRIM", FS_PUBLIC, TIME , 0 }, +{ "LTRIM", FS_PUBLIC, LTRIM , 0 }, +{ "RTRIM", FS_PUBLIC, RTRIM , 0 }, +{ "ALLTRIM", FS_PUBLIC, ALLTRIM , 0 } +}; + diff --git a/harbour/tests/broken/runner.c b/harbour/tests/working/runner.c similarity index 78% rename from harbour/tests/broken/runner.c rename to harbour/tests/working/runner.c index 6ae0d8a917..f9c023e72f 100644 --- a/harbour/tests/broken/runner.c +++ b/harbour/tests/working/runner.c @@ -1,6 +1,7 @@ #include "pcode.h" #include + /* #if DOS32 */ static BYTE prgFunction[] = { 0x68, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, @@ -37,9 +38,14 @@ typedef struct #define SYM_FUNC 1 /* Defined function */ #define SYM_EXTERN 2 /* Previously defined function */ -PASM_CALL CreateFun( PSYMBOL, PBYTE ); /* Create a dynamic function*/ +#define SYM_NOT_FOUND 0xFFFFFFFF /* Symbol not found. FindSymbol */ -HARBOUR Runner(); +PASM_CALL CreateFun( PSYMBOL, PBYTE ); /* Create a dynamic function*/ +HARBOUR HB_RUN(); +void PushSymbol( PSYMBOL ); +void PushNil( void ); +void Do( WORD ); +ULONG FindSymbol( char *, PDYNFUNC, ULONG ); #include "run_exp.h" /* @@ -52,13 +58,10 @@ HARBOUR Runner(); * */ -/* Same story. - - All the function pointers of the internal functions - Including Runner itself, since the first symbol gets executed by Harbour ;-) -*/ #include +ULONG ulSymEntry = 0; /* Link enhancement */ + /* Runner @@ -68,7 +71,7 @@ HARBOUR Runner(); In due time it should also be able to collect the data from the binary/executable itself */ -HARBOUR Runner( void ) +HARBOUR HB_RUN( void ) /* HB_Run( ) */ { char cLong[4]; /* Temporary long */ char *szFileName; @@ -80,7 +83,7 @@ HARBOUR Runner( void ) ULONG ulSymbols; /* Number of symbols */ ULONG ulFuncs; /* Number of functions */ ULONG ulSize; /* Size of function */ - ULONG ul, ul2; + ULONG ul, ulPos; BYTE bCont; @@ -101,7 +104,6 @@ HARBOUR Runner( void ) ( (BYTE) cLong[1] ) * 0x100 + ( (BYTE) cLong[2] ) * 0x10000 + ( (BYTE) cLong[3] ) * 0x1000000; - printf("\nNumber of symbols=%li\n", ulSymbols ); pSymRead = _xgrab( ulSymbols * sizeof( SYMBOL ) ); @@ -122,7 +124,6 @@ HARBOUR Runner( void ) pSymRead[ ul ].szName = (char *) _xgrab( szIdx - szTemp + 1 ); strcpy( pSymRead[ ul ].szName, szTemp ); - printf("\nName = %s.", pSymRead[ ul].szName ); fread( szTemp, 2, 1, file ); @@ -136,7 +137,6 @@ HARBOUR Runner( void ) ( (BYTE) cLong[1] ) * 0x100 + ( (BYTE) cLong[2] ) * 0x10000 + ( (BYTE) cLong[3] ) * 0x1000000; - printf("\nNumber of functions=%li\n", ulFuncs ); pPCode = ( PDYNFUNC ) _xgrab( ulFuncs * sizeof( DYNFUNC ) ); for( ul=0; ul < ulFuncs; ul++) /* Read symbols in .HRB */ @@ -151,7 +151,7 @@ HARBOUR Runner( void ) else bCont = FALSE; } while( bCont ); - printf("\nName = %s.", szTemp ); + printf("\nLoading <%s>", szTemp ); pPCode[ ul ].szName = (char *) _xgrab( szIdx - szTemp + 1); strcpy( pPCode[ ul ].szName, szTemp ); @@ -160,7 +160,6 @@ HARBOUR Runner( void ) ( (BYTE) cLong[1] ) * 0x100 + ( (BYTE) cLong[2] ) * 0x10000 + ( (BYTE) cLong[3] ) * 0x1000000 + 1; - printf("\nSize of function=%li\n", ulSize ); pPCode[ ul ].pCode = _xgrab( ulSize ); fread( pPCode[ ul ].pCode, 1, ulSize, file ); /* Read the block */ @@ -170,15 +169,18 @@ HARBOUR Runner( void ) /* function */ } - ul2 = 0; - for( ul = 0; ul < ulSymbols; ul++ ) /* Quick & Dirty linking */ + ulSymEntry = 0; + for( ul = 0; ul < ulSymbols; ul++ ) /* Linker */ { - if( ( (ULONG) pSymRead[ ul ].pFunPtr ) == SYM_FUNC ) - { /* Internal function */ - pSymRead[ ul ].pFunPtr = pPCode[ ul2++ ].pAsmCall->pFunPtr; + { + ulPos = FindSymbol( pSymRead[ ul ].szName, pPCode, ulFuncs ); + if( ulPos != SYM_NOT_FOUND ) + pSymRead[ ul ].pFunPtr = pPCode[ ulPos ].pAsmCall->pFunPtr; + else + pSymRead[ ul ].pFunPtr = (void *) SYM_EXTERN; } - else if( ( (ULONG) pSymRead[ ul ].pFunPtr ) == SYM_EXTERN ) + if( ( (ULONG) pSymRead[ ul ].pFunPtr ) == SYM_EXTERN ) { /* External function */ pDynSym = FindDynSym( pSymRead[ ul ].szName ); if( !pDynSym ) @@ -191,7 +193,33 @@ HARBOUR Runner( void ) } } - pSymRead[ 0 ].pFunPtr(); /* Run the thing !!! */ + ProcessSymbols( pSymRead, ulSymbols ); + + for( ul = 0; ul < ulSymbols; ul++ ) /* Check INIT functions */ + { + if( pSymRead[ ul ].cScope & FS_INIT ) + { + PushSymbol( pSymRead + ul ); + PushNil(); + Do( 0 ); /* Run init function */ + } + } + + PushSymbol( pSymRead ); + PushNil(); + Do( 0 ); /* Run the thing !!! */ + + for( ul = 0; ul < ulSymbols; ul++ ) /* Check EXIT functions */ + { + if( pSymRead[ ul ].cScope & FS_EXIT ) + { + PushSymbol( pSymRead + ul ); + PushNil(); + Do( 0 ); /* Run exit function */ + pSymRead[ ul ].cScope = pSymRead[ ul ].cScope & (~FS_EXIT); + /* Exit function cannot be handled by main() in hvm.c */ + } + } for( ul = 0; ul < ulFuncs; ul++ ) { @@ -218,6 +246,31 @@ HARBOUR Runner( void ) } } +ULONG FindSymbol( char *szName, PDYNFUNC pPCode, ULONG ulLoaded ) +{ + ULONG ulRet; + BYTE bFound; + + if( ( ulSymEntry < ulLoaded ) && /* Is it a normal list ? */ + !strcmp( szName, pPCode[ ulSymEntry ].szName ) ) + ulRet = ulSymEntry++; + else + { + bFound = FALSE; + ulRet = 0; + while( !bFound && ulRet < ulLoaded ) + { + if( !strcmp( szName, pPCode[ ulRet ].szName ) ) + bFound = TRUE; + else + ulRet++; + } + if( !bFound ) + ulRet = SYM_NOT_FOUND; + } + return( ulRet ); +} + /* Patch an address of the dynamic function */ void Patch( PBYTE pCode, ULONG ulOffset, void *Address ) { @@ -266,7 +319,7 @@ void PatchRelative( PBYTE pCode, ULONG ulOffset, void *Address, ULONG ulNext ) be create dynamically at run-time. If a .PRG contains 10 functions, 10 dynamic functions are created which - are all the same :-) except for 1 pointer. + are all the same :-) except for 2 pointers. */ PASM_CALL CreateFun( PSYMBOL pSymbols, PBYTE pCode ) { diff --git a/harbour/tests/working/spawn.prg b/harbour/tests/working/spawn.prg new file mode 100644 index 0000000000..40cff54e33 --- /dev/null +++ b/harbour/tests/working/spawn.prg @@ -0,0 +1,11 @@ +// +// Spawn() +// +// This program adds a .HRB at run-time +// +function Main() + + QOut( "We are now in spawn" ) + HB_Run( "Hello.hrb" ) // Load & Run Hello.hrb + QOut( "We are back again" ) +return nil diff --git a/harbour/tests/broken/hrb.bat b/harbour/tests/working/stub.bat similarity index 61% rename from harbour/tests/broken/hrb.bat rename to harbour/tests/working/stub.bat index 56271c56ba..d46a46b155 100644 --- a/harbour/tests/broken/hrb.bat +++ b/harbour/tests/working/stub.bat @@ -1,5 +1,5 @@ @echo off REM From .PRG to .C = Harbour -..\..\bin\harbour %1.prg /n /gh +..\..\bin\harbour %1.prg /n /gHRB runner %1.hrb