From 4522500293c018640034833809bf48ddf16ad327 Mon Sep 17 00:00:00 2001 From: Przemyslaw Czerpak Date: Tue, 13 Oct 2009 13:17:15 +0000 Subject: [PATCH] 2009-10-13 15:16 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/include/hbpp.h * harbour/include/hbcompdf.h * harbour/src/pp/ppcore.c * harbour/src/compiler/hbmain.c * harbour/src/compiler/cmdcheck.c * harbour/src/compiler/ppcomp.c * harbour/src/compiler/hbusage.c * harbour/doc/man/harbour.1 + added support for new compiler switch -sm which can be used to generate dependencies list. * modified HB_COMPILEBUF() function to return dependencies list instead of .HRB file body when -sm switch is used. Files in single module are separated by spaces and modules are separated by TABs (chr(9)) To reduce overhead I suggest to use in programs like hbmk2 together with -sm also -kj switch - it disables some time consuming optimizations in compiler code. --- harbour/ChangeLog | 19 ++++++++ harbour/doc/man/harbour.1 | 4 +- harbour/include/hbcompdf.h | 9 ++++ harbour/include/hbpp.h | 7 +++ harbour/src/compiler/cmdcheck.c | 45 +++++++++++++++--- harbour/src/compiler/hbmain.c | 82 ++++++++++++++++++++++++++++++--- harbour/src/compiler/hbusage.c | 4 +- harbour/src/compiler/ppcomp.c | 28 +++++++++++ harbour/src/pp/ppcore.c | 14 ++++++ 9 files changed, 195 insertions(+), 17 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 470b94da54..0431b879de 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,25 @@ past entries belonging to author(s): Viktor Szakats. */ +2009-10-13 15:16 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/include/hbpp.h + * harbour/include/hbcompdf.h + * harbour/src/pp/ppcore.c + * harbour/src/compiler/hbmain.c + * harbour/src/compiler/cmdcheck.c + * harbour/src/compiler/ppcomp.c + * harbour/src/compiler/hbusage.c + * harbour/doc/man/harbour.1 + + added support for new compiler switch -sm which can be used to + generate dependencies list. + * modified HB_COMPILEBUF() function to return dependencies list + instead of .HRB file body when -sm switch is used. Files in + single module are separated by spaces and modules are separated + by TABs (chr(9)) + To reduce overhead I suggest to use in programs like hbmk2 + together with -sm also -kj switch - it disables some time + consuming optimizations in compiler code. + 2009-10-13 12:40 UTC+0200 Viktor Szakats (harbour.01 syenar.hu) * contrib/hbwin/win_prn2.c ! alter hb_PrintFileRaw() to open printed file in FILE_SHARE_READ mode. diff --git a/harbour/doc/man/harbour.1 b/harbour/doc/man/harbour.1 index f983582df3..a7802c1b54 100644 --- a/harbour/doc/man/harbour.1 +++ b/harbour/doc/man/harbour.1 @@ -64,8 +64,8 @@ quiet quiet and don't display program header .IP "\fB-r=\fP" 10 set maximum number of preprocessor iterations -.IP "\fB-s\fP" 10 -syntax check only +.IP "\fB-s[m]\fP" 10 +syntax check only [and generate dependencies list] .IP "\fB-u[]\fP" 10 use command def set in (or none) .IP "\fB-u+\fP" 10 diff --git a/harbour/include/hbcompdf.h b/harbour/include/hbcompdf.h index a162d58b95..3afc7a9bca 100644 --- a/harbour/include/hbcompdf.h +++ b/harbour/include/hbcompdf.h @@ -618,6 +618,13 @@ typedef struct _HB_EXPRLST } HB_EXPRLST, * PHB_EXPRLST; +typedef struct _HB_INCLST +{ + struct _HB_INCLST *pNext; + char szFileName[ 1 ]; +} +HB_INCLST, * PHB_INCLST; + typedef struct _HB_COMP { /* common to macro compiler members */ @@ -636,6 +643,7 @@ typedef struct _HB_COMP PEXTERN externs; PHB_MODULE modules; PHB_VARTYPE pVarType; + PHB_INCLST incfiles; PCOMDECLARED pFirstDeclared; PCOMDECLARED pLastDeclared; @@ -689,6 +697,7 @@ typedef struct _HB_COMP int iLanguage; /* default Harbour generated output language */ int iGenCOutput; /* C code generation should be verbose (use comments) or not */ int ilastLineErr; /* line numer with last syntax error */ + int iTraceInclude; /* trace included files and generate dependencies list */ BOOL fQuiet; /* be quiet during compilation (-q) */ BOOL fFullQuiet; /* be quiet during compilation disable all messages */ diff --git a/harbour/include/hbpp.h b/harbour/include/hbpp.h index af40569ec2..6982715150 100644 --- a/harbour/include/hbpp.h +++ b/harbour/include/hbpp.h @@ -116,6 +116,11 @@ typedef HB_PP_INLINE_FUNC * PHB_PP_INLINE_FUNC; typedef HB_PP_SWITCH_FUNC_( HB_PP_SWITCH_FUNC ); typedef HB_PP_SWITCH_FUNC * PHB_PP_SWITCH_FUNC; +/* function to register included files */ +#define HB_PP_INC_FUNC_( func ) void func( void *, const char * ) +typedef HB_PP_INC_FUNC_( HB_PP_INC_FUNC ); +typedef HB_PP_INC_FUNC * PHB_PP_INC_FUNC; + /* preprocessor tokens */ #define HB_PP_TOKEN_NUL 0 @@ -620,6 +625,7 @@ typedef struct PHB_PP_ERROR_FUNC pErrorFunc; /* function to generate errors */ PHB_PP_DISP_FUNC pDispFunc; /* function to redirect stdout messages */ PHB_PP_DUMP_FUNC pDumpFunc; /* function for catching #pragma dump data */ + PHB_PP_INC_FUNC pIncFunc; /* function to register included files */ PHB_PP_INLINE_FUNC pInLineFunc; /* function for hb_inLine(...) {...} blocks */ PHB_PP_SWITCH_FUNC pSwitchFunc; /* function for compiler switches with #pragma ... */ } @@ -646,6 +652,7 @@ extern void hb_pp_init( PHB_PP_STATE pState, BOOL fQuiet, PHB_PP_DUMP_FUNC pDumpFunc, PHB_PP_INLINE_FUNC pInLineFunc, PHB_PP_SWITCH_FUNC pSwitchFunc ); extern void hb_pp_initDynDefines( PHB_PP_STATE pState, BOOL fArchDefs ); +extern void hb_pp_setIncFunc( PHB_PP_STATE pState, PHB_PP_INC_FUNC pIncFunc ); extern void hb_pp_readRules( PHB_PP_STATE pState, const char * szRulesFile ); extern void hb_pp_setStdRules( PHB_PP_STATE pState ); extern void hb_pp_setStdBase( PHB_PP_STATE pState ); diff --git a/harbour/src/compiler/cmdcheck.c b/harbour/src/compiler/cmdcheck.c index ad6e669c56..7d986b7588 100644 --- a/harbour/src/compiler/cmdcheck.c +++ b/harbour/src/compiler/cmdcheck.c @@ -537,10 +537,30 @@ static void hb_compChkEnvironVar( HB_COMP_DECL, const char *szSwitch ) case 's': case 'S': - if( *( s + 1 ) == '-' ) - HB_COMP_PARAM->fSyntaxCheckOnly = FALSE; - else - HB_COMP_PARAM->fSyntaxCheckOnly = TRUE; + switch( *( s + 1 ) ) + { + case '\0': + HB_COMP_PARAM->fSyntaxCheckOnly = TRUE; + break; + case '-': + HB_COMP_PARAM->fSyntaxCheckOnly = FALSE; + HB_COMP_PARAM->iTraceInclude = 0; + break; + case 'm': + case 'M': + if( s[2] == '-' || s[2]=='0' ) + { + HB_COMP_PARAM->iTraceInclude = 0; + break; + } + else if ( s[2] == '\0' || s[2] == '1' ) + { + HB_COMP_PARAM->iTraceInclude = 1; + break; + } + default: + hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'F', HB_COMP_ERR_BADOPTION, s, NULL ); + } break; case 't': @@ -892,7 +912,7 @@ void hb_compChkCompilerSwitch( HB_COMP_DECL, int iArg, const char * const Args[] case 'q': case 'Q': - if( szSwitch[j + 1] && HB_ISDIGIT( szSwitch[j + 1] ) ) + if( HB_ISDIGIT( szSwitch[j + 1] ) ) { Switch[2] = szSwitch[j + 1]; Switch[3] = '\0'; @@ -916,6 +936,19 @@ void hb_compChkCompilerSwitch( HB_COMP_DECL, int iArg, const char * const Args[] j = strlen( szSwitch ) - 1; break; + case 's': + case 'S': + ++j; + Switch[2] = Switch[3] = Switch[4] = '\0'; + if( szSwitch[j] == 'm' || szSwitch[j] == 'M' ) + { + Switch[2] = szSwitch[j++]; + if( HB_ISDIGIT( szSwitch[j] ) || szSwitch[j] == '-' ) + Switch[3] = szSwitch[j++]; + } + hb_compChkEnvironVar( HB_COMP_PARAM, Switch ); + continue; + case 'u': case 'U': szSwitch += ( j - 1 ); @@ -927,7 +960,7 @@ void hb_compChkCompilerSwitch( HB_COMP_DECL, int iArg, const char * const Args[] case 'w': case 'W': - if( szSwitch[j + 1] && HB_ISDIGIT( szSwitch[j + 1] ) ) + if( HB_ISDIGIT( szSwitch[j + 1] ) ) { Switch[2] = szSwitch[j + 1]; Switch[3] = '\0'; diff --git a/harbour/src/compiler/hbmain.c b/harbour/src/compiler/hbmain.c index bfd5139e98..e9250df085 100644 --- a/harbour/src/compiler/hbmain.c +++ b/harbour/src/compiler/hbmain.c @@ -83,7 +83,10 @@ int hb_compMain( int argc, const char * const argv[], { if( pBufPtr && pulSize ) { - HB_COMP_PARAM->iLanguage = HB_LANG_PORT_OBJ_BUF; + if( HB_COMP_PARAM->iTraceInclude > 0 ) + HB_COMP_PARAM->iTraceInclude |= 0x100; + else + HB_COMP_PARAM->iLanguage = HB_LANG_PORT_OBJ_BUF; } if( HB_COMP_PARAM->fLogo ) @@ -430,7 +433,7 @@ void hb_compVariableAdd( HB_COMP_DECL, const char * szVarName, PHB_VARTYPE pVarT { char buffer[ 80 ]; hb_snprintf( buffer, sizeof( buffer ), - "Wrong type of codeblock parameter, is: %d, should be: %d\r\n", + "Wrong type of codeblock parameter, is: %d, should be: %d\n", HB_COMP_PARAM->iVarScope, VS_PARAMETER ); hb_compOutErr( HB_COMP_PARAM, buffer ); /* variable defined in a codeblock */ @@ -3709,6 +3712,8 @@ static void hb_compGenOutput( HB_COMP_DECL, int iLanguage ) break; case HB_LANG_PORT_OBJ_BUF: + if( HB_COMP_PARAM->pOutBuf ) + hb_xfree( HB_COMP_PARAM->pOutBuf ); hb_compGenBufPortObj( HB_COMP_PARAM, &HB_COMP_PARAM->pOutBuf, &HB_COMP_PARAM->ulOutBufSize ); break; @@ -3831,7 +3836,7 @@ void hb_compCompileEnd( HB_COMP_DECL ) { PEXTERN pExtern = HB_COMP_PARAM->externs; - HB_COMP_PARAM->externs = HB_COMP_PARAM->externs->pNext; + HB_COMP_PARAM->externs = pExtern->pNext; hb_xfree( pExtern ); } @@ -3839,10 +3844,18 @@ void hb_compCompileEnd( HB_COMP_DECL ) { PHB_MODULE pModule = HB_COMP_PARAM->modules; - HB_COMP_PARAM->modules = HB_COMP_PARAM->modules->pNext; + HB_COMP_PARAM->modules = pModule->pNext; hb_xfree( pModule ); } + while( HB_COMP_PARAM->incfiles ) + { + PHB_INCLST pIncFile = HB_COMP_PARAM->incfiles; + + HB_COMP_PARAM->incfiles = pIncFile->pNext; + hb_xfree( pIncFile ); + } + while( HB_COMP_PARAM->inlines.pFirst ) { PINLINE pInline = HB_COMP_PARAM->inlines.pFirst; @@ -3891,6 +3904,54 @@ void hb_compCompileEnd( HB_COMP_DECL ) } } +static void hb_compGenIncluded( HB_COMP_DECL ) +{ + if( HB_COMP_PARAM->iTraceInclude > 0 && HB_COMP_PARAM->incfiles ) + { + PHB_INCLST pIncFile = HB_COMP_PARAM->incfiles; + + if( HB_COMP_PARAM->iTraceInclude > 0x100 ) + { + ULONG ulLen = 0, u; + BYTE * buffer; + + while( pIncFile ) + { + ulLen += ( ULONG ) strlen( pIncFile->szFileName ) + 1; + pIncFile = pIncFile->pNext; + } + HB_COMP_PARAM->pOutBuf = ( BYTE * ) hb_xrealloc( + HB_COMP_PARAM->pOutBuf, HB_COMP_PARAM->ulOutBufSize + ulLen + 1 ); + buffer = HB_COMP_PARAM->pOutBuf + HB_COMP_PARAM->ulOutBufSize; + HB_COMP_PARAM->ulOutBufSize += ulLen; + pIncFile = HB_COMP_PARAM->incfiles; + while( pIncFile ) + { + u = ( ULONG ) strlen( pIncFile->szFileName ); + memcpy( buffer, pIncFile->szFileName, u ); + buffer +=u; + pIncFile = pIncFile->pNext; + *buffer++ = pIncFile ? ' ' : '\t'; + } + *buffer = '\0'; + } + else + { + BOOL fFullQuiet = HB_COMP_PARAM->fFullQuiet; + HB_COMP_PARAM->fFullQuiet = FALSE; + while( pIncFile ) + { + if( pIncFile != HB_COMP_PARAM->incfiles ) + hb_compOutStd( HB_COMP_PARAM, " " ); + hb_compOutStd( HB_COMP_PARAM, pIncFile->szFileName ); + pIncFile = pIncFile->pNext; + } + hb_compOutStd( HB_COMP_PARAM, "\n" ); + HB_COMP_PARAM->fFullQuiet = fFullQuiet; + } + } +} + static int hb_compCompile( HB_COMP_DECL, const char * szPrg, const char * szBuffer ) { char buffer[ HB_PATH_MAX * 2 + 80 ]; @@ -4150,8 +4211,14 @@ static int hb_compCompile( HB_COMP_DECL, const char * szPrg, const char * szBuff } } - if( ! HB_COMP_PARAM->fSyntaxCheckOnly && fGenCode && - HB_COMP_PARAM->iErrorCount == 0 ) + if( HB_COMP_PARAM->iTraceInclude > 0 ) + { + if( fGenCode && HB_COMP_PARAM->iErrorCount == 0 ) + hb_compGenIncluded( HB_COMP_PARAM ); + fGenCode = FALSE; + } + else if( ! HB_COMP_PARAM->fSyntaxCheckOnly && fGenCode && + HB_COMP_PARAM->iErrorCount == 0 ) { const char * szFirstFunction = NULL; int iFunctionCount = 0; @@ -4213,7 +4280,8 @@ static int hb_compCompile( HB_COMP_DECL, const char * szPrg, const char * szBuff else fGenCode = FALSE; - if( !fGenCode&& !HB_COMP_PARAM->fExit && !HB_COMP_PARAM->fSyntaxCheckOnly ) + if( !fGenCode&& !HB_COMP_PARAM->fExit && + !HB_COMP_PARAM->fSyntaxCheckOnly && HB_COMP_PARAM->iTraceInclude == 0 ) hb_compOutStd( HB_COMP_PARAM, "\nNo code generated.\n" ); hb_compCompileEnd( HB_COMP_PARAM ); diff --git a/harbour/src/compiler/hbusage.c b/harbour/src/compiler/hbusage.c index acc2121728..f1404de2e3 100644 --- a/harbour/src/compiler/hbusage.c +++ b/harbour/src/compiler/hbusage.c @@ -97,7 +97,7 @@ void hb_compPrintUsage( HB_COMP_DECL, const char * szSelf ) "\n %cq0 quiet and don't display program header", "\n %cr: set maximum number of preprocessor iterations", /* TODO: "\n %cr[] request linker to search (or none)", */ - "\n %cs syntax check only", + "\n %cs[m] syntax check only [and generate dependencies list]", /* TODO: "\n %ct path for temp file creation", */ "\n %cu[] use command def set in (or none)", "\n %cu+ add command def set from ", @@ -122,7 +122,7 @@ void hb_compPrintUsage( HB_COMP_DECL, const char * szSelf ) for( iLine = 0; iLine < ( int ) ( sizeof( szOptions ) / sizeof( char * ) ); iLine++ ) { hb_snprintf( buffer, sizeof( buffer ), - szOptions[ iLine ], HB_OS_OPT_DELIM_LIST[ 0 ] ); + szOptions[ iLine ], HB_OS_OPT_DELIM_LIST[ 0 ] ); hb_compOutStd( HB_COMP_PARAM, buffer ); } } diff --git a/harbour/src/compiler/ppcomp.c b/harbour/src/compiler/ppcomp.c index 00f15e5758..4b9cde8087 100644 --- a/harbour/src/compiler/ppcomp.c +++ b/harbour/src/compiler/ppcomp.c @@ -272,6 +272,31 @@ static BOOL hb_pp_CompilerSwitch( void * cargo, const char * szSwitch, return fError; } +static void hb_pp_fileIncluded( void * cargo, const char * szFileName ) +{ + HB_COMP_DECL = ( HB_COMP_PTR ) cargo; + PHB_INCLST pIncFile, * pIncFilePtr; + int iLen; + + pIncFilePtr = &HB_COMP_PARAM->incfiles; + while( *pIncFilePtr ) + { +#if defined( HB_OS_UNIX ) + if( strcmp( ( *pIncFilePtr )->szFileName, szFileName ) == 0 ) + return; +#else + if( hb_stricmp( ( *pIncFilePtr )->szFileName, szFileName ) == 0 ) + return; +#endif + pIncFilePtr = &( *pIncFilePtr )->pNext; + } + + iLen = ( int ) strlen( szFileName ); + pIncFile = ( PHB_INCLST ) hb_xgrab( sizeof( HB_INCLST ) + iLen ); + pIncFile->pNext = NULL; + memcpy( pIncFile->szFileName, szFileName, iLen + 1 ); + *pIncFilePtr = pIncFile; +} void hb_compInitPP( HB_COMP_DECL, int argc, const char * const argv[] ) { @@ -286,6 +311,9 @@ void hb_compInitPP( HB_COMP_DECL, int argc, const char * const argv[] ) HB_COMP_ISSUPPORTED( HB_COMPFLAG_HB_INLINE ) ? hb_pp_hb_inLine : NULL, hb_pp_CompilerSwitch ); + if( HB_COMP_PARAM->iTraceInclude ) + hb_pp_setIncFunc( HB_COMP_PARAM->pLex->pPP, hb_pp_fileIncluded ); + if( ! HB_COMP_PARAM->szStdCh ) hb_pp_setStdRules( HB_COMP_PARAM->pLex->pPP ); else if( HB_COMP_PARAM->szStdCh[ 0 ] > ' ' ) diff --git a/harbour/src/pp/ppcore.c b/harbour/src/pp/ppcore.c index e477952239..b9980ca833 100644 --- a/harbour/src/pp/ppcore.c +++ b/harbour/src/pp/ppcore.c @@ -1931,6 +1931,9 @@ static PHB_PP_FILE hb_pp_FileNew( PHB_PP_STATE pState, const char * szFileName, if( ! file_in ) return NULL; + + if( pState->pIncFunc ) + ( pState->pIncFunc )( pState->cargo, szFileName ); } pFile = ( PHB_PP_FILE ) hb_xgrab( sizeof( HB_PP_FILE ) ); @@ -2151,6 +2154,12 @@ static void hb_pp_pragmaStreamFile( PHB_PP_STATE pState, const char * szFileName hb_membufPtr( pState->pStreamBuffer ), hb_membufLen( pState->pStreamBuffer ) ); } + if( pState->pFuncOut || pState->pFuncEnd ) + { + hb_pp_tokenAdd( &pState->pNextTokenPtr, "\n", 1, 0, HB_PP_TOKEN_EOL | HB_PP_TOKEN_STATIC ); + pState->pFile->iTokens++; + pState->fNewStatement = TRUE; + } hb_membufFlush( pState->pStreamBuffer ); } else @@ -5269,6 +5278,11 @@ void hb_pp_init( PHB_PP_STATE pState, BOOL fQuiet, int iCycles, void * cargo, pState->pSwitchFunc = pSwitchFunc; } +void hb_pp_setIncFunc( PHB_PP_STATE pState, PHB_PP_INC_FUNC pIncFunc ) +{ + pState->pIncFunc = pIncFunc; +} + /* * reset PP context, used for multiple .prg file compilation * with DO ... or *.clp files