diff --git a/harbour/ChangeLog b/harbour/ChangeLog index bc5652ef23..87ffe4d8c5 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,63 @@ 2002-12-01 13:30 UTC+0100 Foo Bar */ + * harbour/bin/hb-mkslib.sh + + added ${L_USR} to gcc parameters + + * harbour/source/pp/ppgen.c + ! fixed minor typo in printf() format + +2006-11-10 02:05 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/include/hbcomp.h + * harbour/include/hbpp.h + * harbour/source/compiler/cmdcheck.c + * harbour/source/compiler/hbusage.c + * harbour/source/compiler/ppcomp.c + * harbour/source/pp/ppcore.c + * harbour/source/pp/ppgen.c + * harbour/source/pp/pplib.c + * restored support for old hb_inLine() syntax + + added support for hb_inLine() to new PP. It can be enabled by + -kI compiler switch. It's disabled by default. + The new hb_inLine{} syntax is: + [ ] hb_inLine [ ( [] ) ] { [ ] } [ ] + can contain new line characters. + Nested hb_inLine{} in is not supported. If you think + it's important I can add it in few lines. + This version does not break any valid Clipper syntax, hb_inLine is + not reserved word and hb_inLine can be repeated many times in the + same line. F.e. this code can be properly preprocessed and compied if + you disable in compiler old hb_inLine() syntax and enable the new one + by -kcI Harbour compiler switch: + + proc main() + local hb_inLine := " (var) " + ? hb_inLine{ hb_retc("inLine"); } + hb_inLine(" parameter ") { + hb_retc( hb_parc( 1 ) ); + } + "!" + hb_inLine + hb_inLine() { hb_retc( ":-)" ); } + ; + hb_inLine() + "{}" + return + function hb_inLine() + return " func() " + + So from user point of view this version have real "inline" syntax. + To be clear: I'm not a fun of any C inline extensions. They works + only when we use .c code as compiler backend so the code which uses + them cannot be used in .hrb files and any other format we will add + in the future which do not support later C code compilation. F.e it + will not work in compiler integrated with HVM or with .NET + Anyhow if someone finds it useful then I think that it should be + properly implemented. This is the reason I added the new version. + The old one I left only for backward compatibility. It breaks any + code which uses hb_inLine keyword can be used only once in a line + and it does not have "inline" so IMHO it should not be enabled by + default. + I would like to hear your opinion about default compiler switches: + 1. should we disable both: hb_inLine() and hb_inLine {} + 2. should we disable hb_inLine() and enable hb_inLine {} + 3. should we disable hb_inLine {} and enable hb_inLine() + 4. should we enable both: hb_inLine() and hb_inLine {} + + harbour/tests/hbinline.prg + added test code for new hb_inLine{} syntax diff --git a/harbour/include/hbcomp.h b/harbour/include/hbcomp.h index 7d35caeca2..7a75e81990 100644 --- a/harbour/include/hbcomp.h +++ b/harbour/include/hbcomp.h @@ -634,6 +634,7 @@ extern unsigned int hb_pp_MaxTranslateCycles; #define HB_COMPFLAG_ARRSTR 8 /* -ks strings as array of bytes */ #define HB_COMPFLAG_OPTJUMP 16 /* -kj turn off jump optimalization */ #define HB_COMPFLAG_RT_MACRO 64 /* -kr */ +#define HB_COMPFLAG_HB_INLINE_PP 128 /* -kI hb_inLine support in PP */ #ifdef HB_MACRO_SUPPORT #define HB_COMP_ISSUPPORTED(flag) ( HB_MACRO_DATA->supported & (flag) ) diff --git a/harbour/include/hbpp.h b/harbour/include/hbpp.h index 5118656a79..c6b9d04048 100644 --- a/harbour/include/hbpp.h +++ b/harbour/include/hbpp.h @@ -66,7 +66,16 @@ HB_EXTERN_BEGIN #define HB_PP_STREAM_CLIPPER 3 /* clipper compatible TEXT/ENDTEXT */ #define HB_PP_STREAM_PRG 4 /* TEXT/ENDTEXT lines joined with LF */ #define HB_PP_STREAM_C 5 /* TEXT/ENDTEXT lines joined and ESC seq processed */ +#define HB_PP_STREAM_INLINE_C 6 /* hb_inLIne() {...} data, should not be preprocessed */ +/* hb_inLine() states */ +#define HB_PP_INLINE_OFF 0 +#define HB_PP_INLINE_START 1 +#define HB_PP_INLINE_PARAM 2 +#define HB_PP_INLINE_BODY 3 +#define HB_PP_INLINE_COMMENT 4 +#define HB_PP_INLINE_QUOTE1 5 +#define HB_PP_INLINE_QUOTE2 6 /* function to open included files */ #define HB_PP_OPEN_FUNC_( func ) FILE * func( char *, BOOL, char * ) @@ -93,6 +102,11 @@ typedef HB_PP_DISP_FUNC * PHB_PP_DISP_FUNC; typedef HB_PP_DUMP_FUNC_( HB_PP_DUMP_FUNC ); typedef HB_PP_DUMP_FUNC * PHB_PP_DUMP_FUNC; +/* function for catching #pragma dump data */ +#define HB_PP_INLINE_FUNC_( func ) void func( char *, char *, ULONG, int ) +typedef HB_PP_INLINE_FUNC_( HB_PP_INLINE_FUNC ); +typedef HB_PP_INLINE_FUNC * PHB_PP_INLINE_FUNC; + /* function for catching #pragma dump data */ #define HB_PP_SWITCH_FUNC_( func ) BOOL func( const char *, int ) typedef HB_PP_SWITCH_FUNC_( HB_PP_SWITCH_FUNC ); @@ -558,6 +572,9 @@ typedef struct PHB_MEM_BUFFER pStreamBuffer; /* buffer for stream output */ int iStreamDump; /* stream output, see HB_PP_STREAM_* */ int iDumpLine; /* line where current dump output begins */ + int iInLineCount; /* number of hb_inLine() functions */ + int iInLineState; /* hb_inLine() state */ + int iInLineBraces; /* braces counter for hb_inLine() */ PHB_PP_FILE pFile; /* currently preprocessed file structure */ int iFiles; /* number of open files */ @@ -567,7 +584,8 @@ 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_SWITCH_FUNC pSwitchFunc; /* function to compiler switches with #pragma ... */ + PHB_PP_INLINE_FUNC pInLineFunc; /* function for hb_inLine(...) {...} blocks */ + PHB_PP_SWITCH_FUNC pSwitchFunc; /* function for compiler switches with #pragma ... */ } HB_PP_STATE, * PHB_PP_STATE; @@ -587,10 +605,12 @@ extern PHB_PP_STATE hb_pp_new( void ); extern void hb_pp_init( PHB_PP_STATE pState, char * szFileName, BOOL fQuiet, PHB_PP_OPEN_FUNC pOpenFunc, PHB_PP_CLOSE_FUNC pCloseFunc, PHB_PP_ERROR_FUNC pErrorFunc, PHB_PP_DISP_FUNC pDispFunc, - PHB_PP_DUMP_FUNC pDumpFunc, PHB_PP_SWITCH_FUNC pSwitchFunc ); + PHB_PP_DUMP_FUNC pDumpFunc, PHB_PP_INLINE_FUNC pInLineFunc, + PHB_PP_SWITCH_FUNC pSwitchFunc ); extern void hb_pp_free( PHB_PP_STATE pState ); extern void hb_pp_reset( PHB_PP_STATE pState ); extern void hb_pp_setStdBase( PHB_PP_STATE pState ); +extern void hb_pp_setStream( PHB_PP_STATE pState, int iMode ); extern void hb_pp_addSearchPath( PHB_PP_STATE pState, const char * szPath, BOOL fReplace ); extern void hb_pp_inFile( PHB_PP_STATE pState, char * szFileName, FILE * file_in ); extern void hb_pp_outFile( PHB_PP_STATE pState, char * szOutFileName, FILE * file_out ); diff --git a/harbour/source/compiler/cmdcheck.c b/harbour/source/compiler/cmdcheck.c index 9907954494..e02030fef2 100644 --- a/harbour/source/compiler/cmdcheck.c +++ b/harbour/source/compiler/cmdcheck.c @@ -685,6 +685,10 @@ void hb_compChkEnvironVar( char *szSwitch ) hb_comp_Supported |= HB_COMPFLAG_HB_INLINE; break; + case 'I': + hb_comp_Supported |= HB_COMPFLAG_HB_INLINE_PP; + break; + case 'J': hb_comp_Supported &= ~HB_COMPFLAG_OPTJUMP; break; diff --git a/harbour/source/compiler/hbusage.c b/harbour/source/compiler/hbusage.c index 6b885e200d..edbae59d50 100644 --- a/harbour/source/compiler/hbusage.c +++ b/harbour/source/compiler/hbusage.c @@ -120,6 +120,7 @@ void hb_compPrintModes( void ) "\nOptions: c clear all flags (strict Clipper mode)", "\n h Harbour mode (default)", "\n i enable support for HB_INLINE", + "\n I enable support for HB_INLINE in PP", "\n r runtime settings enabled", "\n s string as bytes array enabled", "\n x extended xbase mode", diff --git a/harbour/source/compiler/ppcomp.c b/harbour/source/compiler/ppcomp.c index fc4b62e4d4..7aba8babe7 100644 --- a/harbour/source/compiler/ppcomp.c +++ b/harbour/source/compiler/ppcomp.c @@ -151,11 +151,42 @@ static void hb_pp_PragmaDump( char * pBuffer, ULONG ulSize, int iLine ) hb_comp_iLine = iSaveLine; } +static void hb_pp_hb_inLine( char * szFunc, char * pBuffer, ULONG ulSize, int iLine ) +{ + int iSaveLine = hb_comp_iLine; + + /* I do not know why but compiler expect line number 1 bigger then + real line number */ + hb_comp_iLine = iLine + 1; + + if( hb_comp_iLanguage != LANG_C && hb_comp_iLanguage != LANG_OBJ_MODULE ) + { + hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_REQUIRES_C, NULL, NULL ); + } + else + { + PINLINE pInline = hb_compInlineAdd( hb_compIdentifierNew( szFunc, TRUE ) ); + pInline->pCode = ( BYTE * ) hb_xgrab( ulSize + 1 ); + memcpy( pInline->pCode, pBuffer, ulSize ); + pBuffer[ ulSize ] = '\0'; + pInline->lPCodeSize = ulSize; + /* + * inform genc.c that hb_inLine function was generated to + * generate #include ... with additional header files + */ + hb_comp_cInlineID = '1'; + } + hb_comp_iLine = iSaveLine; +} + static BOOL hb_pp_CompilerSwitch( const char * szSwitch, int iValue ) { BOOL fError = FALSE; int i = strlen( szSwitch ); + if( i > 1 && szSwitch[ i - 1 ] - '0' == iValue ) + --i; + if( i == 1 ) { switch( szSwitch[ 0 ] ) @@ -214,22 +245,7 @@ static BOOL hb_pp_CompilerSwitch( const char * szSwitch, int iValue ) } else if( i == 2 ) { - if( szSwitch[ 1 ] - '0' == iValue && iValue >= 0 && iValue <= 3 && - ( szSwitch[ 0 ] == 'w' || szSwitch[ 0 ] == 'W' ) && - ( iValue >= 0 && iValue <= 3 ) ) - hb_comp_iWarnings = iValue; - else if( hb_stricmp( szSwitch, "es" ) == 0 && - ( iValue == HB_EXITLEVEL_DEFAULT || - iValue == HB_EXITLEVEL_SETEXIT || - iValue == HB_EXITLEVEL_DELTARGET ) ) - hb_comp_iExitLevel = iValue; - else - fError = TRUE; - } - else if( i == 3 ) - { - if( szSwitch[ 2 ] - '0' == iValue && - hb_strnicmp( szSwitch, "es", 2 ) == 0 && + if( hb_strnicmp( szSwitch, "es", 2 ) == 0 && ( iValue == HB_EXITLEVEL_DEFAULT || iValue == HB_EXITLEVEL_SETEXIT || iValue == HB_EXITLEVEL_DELTARGET ) ) @@ -264,7 +280,8 @@ void hb_pp_SetRules( BOOL fQuiet, int argc, char * argv[] ) hb_pp_init( s_pp_state, szStdCh, fQuiet, hb_pp_IncludeOpen, hb_pp_IncludeClose, hb_pp_ErrorGen, NULL, hb_pp_PragmaDump, - hb_pp_CompilerSwitch ); + HB_COMP_ISSUPPORTED( HB_COMPFLAG_HB_INLINE_PP ) ? + hb_pp_hb_inLine : NULL, hb_pp_CompilerSwitch ); /* Add /D and /undef: command line or envvar defines */ hb_compChkDefines( argc, argv ); @@ -322,7 +339,6 @@ int hb_pp_Internal( FILE * handl_o, char * sOut ) HB_TRACE(HB_TR_DEBUG, ("hb_pp_Internal(%p, %s)", handl_o, sOut)); - hb_pp_StreamBlock = 0; hb_pp_NestedLiteralString = FALSE; hb_pp_LiteralEscSeq = FALSE; @@ -349,6 +365,9 @@ int hb_pp_Internal( FILE * handl_o, char * sOut ) hb_comp_yyppo = NULL; } + if( hb_pp_StreamBlock == HB_PP_STREAM_DUMP_C ) + hb_pp_setStream( s_pp_state, HB_PP_STREAM_INLINE_C ); + szLine = hb_pp_nextLine( s_pp_state, &ulLen ); /* I do not know why but compiler expect line number 1 bigger then real line number */ diff --git a/harbour/source/pp/ppcore.c b/harbour/source/pp/ppcore.c index 2400e30bf6..928f82586c 100644 --- a/harbour/source/pp/ppcore.c +++ b/harbour/source/pp/ppcore.c @@ -520,6 +520,28 @@ static void hb_pp_tokenAddNext( PHB_PP_STATE pState, const char * value, ULONG u pState->iSpaces = 0; pState->iLastType = HB_PP_TOKEN_TYPE( type ); + + if( pState->iInLineState != HB_PP_INLINE_OFF ) + { + if( pState->iInLineState == HB_PP_INLINE_START && + pState->iLastType == HB_PP_TOKEN_LEFT_PB ) + { + pState->iInLineState = HB_PP_INLINE_PARAM; + pState->iInLineBraces = 1; + } + else if( pState->iInLineState == HB_PP_INLINE_PARAM ) + { + if( pState->iLastType == HB_PP_TOKEN_LEFT_PB ) + pState->iInLineBraces++; + else if( pState->iLastType == HB_PP_TOKEN_RIGHT_PB ) + { + if( --pState->iInLineBraces == 0 ) + pState->iInLineState = HB_PP_INLINE_BODY; + } + } + else + pState->iInLineState = HB_PP_INLINE_OFF; + } } static void hb_pp_tokenAddStreamFunc( PHB_PP_STATE pState, PHB_PP_TOKEN pToken, @@ -702,16 +724,20 @@ static void hb_pp_dumpEnd( PHB_PP_STATE pState ) static void hb_pp_getLine( PHB_PP_STATE pState ) { + PHB_PP_TOKEN * pInLinePtr; char * pBuffer, ch; ULONG ulLen, ul; BOOL fDump = FALSE; + pInLinePtr = NULL; hb_pp_tokenListFree( &pState->pFile->pTokenList ); pState->pNextTokenPtr = &pState->pFile->pTokenList; pState->pFile->iTokens = pState->iSpaces = 0; pState->fCanNextLine = pState->fDirective = FALSE; pState->fNewStatement = TRUE; pState->iLastType = HB_PP_TOKEN_NUL; + pState->iInLineState = HB_PP_INLINE_OFF; + pState->iInLineBraces = 0; do { @@ -760,6 +786,83 @@ static void hb_pp_getLine( PHB_PP_STATE pState ) } } } + else if( pState->iStreamDump == HB_PP_STREAM_INLINE_C ) + { + if( ulLen > 0 ) + { + ++ul; + switch( pState->iInLineState ) + { + case HB_PP_INLINE_QUOTE1: + if( ch == '\'' ) + pState->iInLineState = HB_PP_INLINE_OFF; + else if( ch == '\\' && ulLen > 1 ) + ++ul; + break; + + case HB_PP_INLINE_QUOTE2: + if( ch == '"' ) + pState->iInLineState = HB_PP_INLINE_OFF; + else if( ch == '\\' && ulLen > 1 ) + ++ul; + break; + + case HB_PP_INLINE_COMMENT: + if( ulLen > 1 && ch == '*' && pBuffer[ 1 ] == '/' ) + pState->iInLineState = HB_PP_INLINE_OFF; + break; + + default: + if( ch == '\'' ) + pState->iInLineState = HB_PP_INLINE_QUOTE1; + else if( ch == '"' ) + pState->iInLineState = HB_PP_INLINE_QUOTE2; + else if( ch == '{' ) + ++pState->iInLineBraces; + else if( ch == '}' ) + { + if( --pState->iInLineBraces == 0 ) + pState->iStreamDump = HB_PP_STREAM_OFF; + } + else if( ulLen > 1 ) + { + if( ch == '/' && pBuffer[ 1 ] == '*' ) + pState->iInLineState = HB_PP_INLINE_COMMENT; + else if( ch == '/' && pBuffer[ 1 ] == '/' ) + ulLen = ul = 0; + } + } + } + if( ul ) + hb_membufAddData( pState->pStreamBuffer, pBuffer, ul ); + + if( ulLen == ul || pState->iStreamDump == HB_PP_STREAM_OFF ) + { + hb_membufAddCh( pState->pStreamBuffer, '\n' ); + if( pState->iStreamDump == HB_PP_STREAM_OFF ) + { + if( pState->pInLineFunc ) + { + char szFunc[ 24 ]; + sprintf( szFunc, "HB_INLINE_%03d", ++pState->iInLineCount ); + if( pInLinePtr && * pInLinePtr ) + hb_pp_tokenSetValue( *pInLinePtr, szFunc, strlen( szFunc ) ); + pState->pInLineFunc( szFunc, + hb_membufPtr( pState->pStreamBuffer ), + hb_membufLen( pState->pStreamBuffer ), + pState->iDumpLine ); + } + else + { + hb_pp_tokenAddNext( pState, + hb_membufPtr( pState->pStreamBuffer ), + hb_membufLen( pState->pStreamBuffer ), + HB_PP_TOKEN_TEXT ); + } + hb_membufFlush( pState->pStreamBuffer ); + } + } + } else if( pState->iStreamDump == HB_PP_STREAM_DUMP_C ) { if( hb_pp_hasCommand( pBuffer, ulLen, &ul, 3, "#", "pragma", "enddump" ) ) @@ -890,18 +993,26 @@ static void hb_pp_getLine( PHB_PP_STATE pState ) #else if( pState->fNewStatement && #endif - ul == 4 && hb_stricmp( "NOTE", pBuffer ) == 0 ) + ul == 4 && hb_strnicmp( "NOTE", pBuffer, 4 ) == 0 ) { /* strip the rest of line */ ul = ulLen; } - /* TODO: hb_inline support, it should be here to not preprocess - the C code, anyhow so far we were living with broken - implementation so probably we can leave with it yet some - time longer */ else { - hb_pp_tokenAddNext( pState, pBuffer, ul, HB_PP_TOKEN_KEYWORD ); + if( pState->pInLineFunc && + pState->iInLineState == HB_PP_INLINE_OFF && + ul == 9 && hb_strnicmp( "hb_inLine", pBuffer, 9 ) == 0 ) + { + if( pState->fCanNextLine ) + hb_pp_tokenAddCmdSep( pState ); + pInLinePtr = pState->pNextTokenPtr; + hb_pp_tokenAddNext( pState, pBuffer, ul, HB_PP_TOKEN_KEYWORD ); + pState->iInLineState = HB_PP_INLINE_START; + pState->iInLineBraces = 0; + } + else + hb_pp_tokenAddNext( pState, pBuffer, ul, HB_PP_TOKEN_KEYWORD ); } } /* This is Clipper incompatible token - such characters are illegal @@ -986,6 +1097,23 @@ static void hb_pp_getLine( PHB_PP_STATE pState ) ++ul; hb_pp_tokenAddNext( pState, pBuffer, ul, HB_PP_TOKEN_MACRO ); } + else if( ch == '{' && !pState->fCanNextLine && + ( pState->iInLineState == HB_PP_INLINE_BODY || + pState->iInLineState == HB_PP_INLINE_START ) ) + { + if( pState->iInLineState == HB_PP_INLINE_START ) + { + hb_pp_tokenAddNext( pState, "(", 1, HB_PP_TOKEN_LEFT_PB | HB_PP_TOKEN_STATIC ); + hb_pp_tokenAddNext( pState, ")", 1, HB_PP_TOKEN_RIGHT_PB | HB_PP_TOKEN_STATIC ); + } + pState->iInLineState = HB_PP_INLINE_OFF; + pState->iStreamDump = HB_PP_STREAM_INLINE_C; + pState->iDumpLine = pState->pFile->iCurrentLine - 1; + if( pState->pStreamBuffer ) + hb_membufFlush( pState->pStreamBuffer ); + else + pState->pStreamBuffer = hb_membufNew(); + } else { PHB_PP_OPERATOR pOperator = hb_pp_operatorFind( pState, pBuffer, ulLen ); @@ -1022,6 +1150,7 @@ static void hb_pp_getLine( PHB_PP_STATE pState ) pState->pFile->fEof ) hb_pp_error( pState, 'E', HB_PP_ERR_MISSING_ENDTEXT, NULL ); } + if( pState->pFile->iTokens != 0 ) { hb_pp_tokenAdd( &pState->pNextTokenPtr, "\n", 1, 0, HB_PP_TOKEN_EOL | HB_PP_TOKEN_STATIC ); @@ -1273,7 +1402,7 @@ static PHB_PP_RULE hb_pp_defineFind( PHB_PP_STATE pState, PHB_PP_TOKEN pToken ) { PHB_PP_RULE pRule = pState->pDefinitions; - /* TODO: create binary tree or hash table - the #define keyword token has + /* TODO% create binary tree or hash table - the #define keyword token has to be unique so it's not necessary to keep the stack list, it will increase the speed when there is a lot of #define values */ @@ -1741,17 +1870,17 @@ static PHB_PP_TOKEN hb_pp_pragmaGetSwitch( PHB_PP_TOKEN pToken, int * piValue ) { if( HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_MINUS ) { - pValue = pToken->pNext; + pValue = pToken; * piValue = 0; } else if( HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_PLUS ) { - pValue = pToken->pNext; + pValue = pToken; * piValue = 1; } else if( HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_NUMBER ) { - pValue = pToken->pNext; + pValue = pToken; * piValue = atoi( pValue->value ); } } @@ -3908,15 +4037,15 @@ static void hb_pp_preprocesToken( PHB_PP_STATE pState ) pToken = pState->pFile->pTokenList; fDirect = HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_DIRECTIVE; pToken = pToken->pNext; - if( !pToken || HB_PP_TOKEN_TYPE( pToken->type ) != HB_PP_TOKEN_KEYWORD ) + if( !pToken ) { fError = TRUE; } #ifndef HB_C52_STRICT /* Harbour PP extension */ - else if( fDirect && pState->pFile->iCurrentLine && + else if( fDirect && pState->pFile->iCurrentLine == 1 && HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_NOT && - pToken->spaces == 0 ) + pToken->spaces == 0 && pState->pFile->pTokenList->spaces == 0 ) { /* ignore first line if it begins with "#!" minor extension which allow to use the same source code @@ -3925,6 +4054,10 @@ static void hb_pp_preprocesToken( PHB_PP_STATE pState ) add support for direct execution compiled .prg files */ } #endif + else if( HB_PP_TOKEN_TYPE( pToken->type ) != HB_PP_TOKEN_KEYWORD ) + { + fError = TRUE; + } else if( hb_pp_tokenValueCmp( pToken, "IFDEF", HB_PP_CMP_DBASE ) ) { hb_pp_condCompile( pState, pToken->pNext, TRUE ); @@ -4268,6 +4401,38 @@ void hb_pp_setStdBase( PHB_PP_STATE pState ) hb_pp_ruleSetStd( pState->pCommands ); } +/* + * set stream mode + */ +void hb_pp_setStream( PHB_PP_STATE pState, int iMode ) +{ + pState->fError = FALSE; + switch( iMode ) + { + case HB_PP_STREAM_DUMP_C: + pState->iDumpLine = pState->pFile ? pState->pFile->iCurrentLine : 0; + if( ! pState->pDumpBuffer ) + pState->pDumpBuffer = hb_membufNew(); + pState->iStreamDump = iMode; + break; + + case HB_PP_STREAM_INLINE_C: + pState->iDumpLine = pState->pFile ? pState->pFile->iCurrentLine : 0; + case HB_PP_STREAM_CLIPPER: + case HB_PP_STREAM_PRG: + case HB_PP_STREAM_C: + if( ! pState->pStreamBuffer ) + pState->pStreamBuffer = hb_membufNew(); + case HB_PP_STREAM_OFF: + case HB_PP_STREAM_COMMENT: + pState->iStreamDump = iMode; + break; + + default: + pState->fError = TRUE; + } +} + /* * initialize PP context */ @@ -4275,7 +4440,8 @@ void hb_pp_init( PHB_PP_STATE pState, char * szStdCh, BOOL fQuiet, PHB_PP_OPEN_FUNC pOpenFunc, PHB_PP_CLOSE_FUNC pCloseFunc, PHB_PP_ERROR_FUNC pErrorFunc, PHB_PP_DISP_FUNC pDispFunc, - PHB_PP_DUMP_FUNC pDumpFunc, PHB_PP_SWITCH_FUNC pSwitchFunc ) + PHB_PP_DUMP_FUNC pDumpFunc, PHB_PP_INLINE_FUNC pInLineFunc, + PHB_PP_SWITCH_FUNC pSwitchFunc ) { pState->fQuiet = fQuiet; pState->pOpenFunc = pOpenFunc; @@ -4283,6 +4449,7 @@ hb_pp_init( PHB_PP_STATE pState, char * szStdCh, BOOL fQuiet, pState->pErrorFunc = pErrorFunc; pState->pDispFunc = pDispFunc; pState->pDumpFunc = pDumpFunc; + pState->pInLineFunc = pInLineFunc; pState->pSwitchFunc = pSwitchFunc; if( !szStdCh ) diff --git a/harbour/source/pp/ppgen.c b/harbour/source/pp/ppgen.c index 89c35cd45f..b17c0b2ef6 100644 --- a/harbour/source/pp/ppgen.c +++ b/harbour/source/pp/ppgen.c @@ -368,7 +368,7 @@ int main( int argc, char * argv[] ) if( szFile ) { - hb_pp_init( pState, NULL, fQuiet, NULL, NULL, NULL, NULL, NULL, NULL ); + hb_pp_init( pState, NULL, fQuiet, NULL, NULL, NULL, NULL, NULL, NULL, NULL ); hb_pp_inFile( pState, szFile, NULL ); if( fWrite ) { diff --git a/harbour/source/pp/pplib.c b/harbour/source/pp/pplib.c index 0621d9325d..29bd9e2e97 100644 --- a/harbour/source/pp/pplib.c +++ b/harbour/source/pp/pplib.c @@ -100,7 +100,7 @@ static PHB_PP_STATE hb_pp_stateParam( int * piParam ) { s_pp_state = hb_pp_new(); hb_pp_init( s_pp_state, NULL, TRUE, NULL, NULL, - hb_pp_ErrorMessage, hb_pp_Disp, NULL, NULL ); + hb_pp_ErrorMessage, hb_pp_Disp, NULL, NULL, NULL ); } return s_pp_state; } diff --git a/harbour/tests/hbinline.prg b/harbour/tests/hbinline.prg new file mode 100644 index 0000000000..1d6cd958ac --- /dev/null +++ b/harbour/tests/hbinline.prg @@ -0,0 +1,26 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * new Hb_inLine{} test + * compile it using -kcI Harbour compiler switch + * + * Copyright 2006 Przemyslaw Czerpak + * www - http://www.harbour-project.org + * + */ + +proc main() +local hb_inLine := " (var) " + +? hb_inLine{ hb_retc("inLine"); } + hb_inLine(" parameter ") { + hb_retc( hb_parc( 1 ) ); + } + "!" + hb_inLine + hb_inLine() { hb_retc( ":-)" ); } + ; + hb_inLine() + "{}" + +return + +function hb_inLine() +return " func() " diff --git a/harbour/tests/inline_c.prg b/harbour/tests/inline_c.prg index 436caf03f0..d2ec011305 100644 --- a/harbour/tests/inline_c.prg +++ b/harbour/tests/inline_c.prg @@ -36,25 +36,24 @@ FUNCTION aTokens( cLine, cDelimiter ) HB_INLINE( aTokens, cLine, Asc( cDelimiter ) ) { // Note including { PHB_ITEM pArray = hb_param( 1, HB_IT_ARRAY ); - PHB_ITEM pLine = hb_param( 2, HB_IT_STRING ); - char cDelimiter = (char) hb_parni(3); - size_t i, iOffset = 0, iIndex = 1; + char cDelimiter = (char) hb_parni(3), * szLine = hb_parc( 2 ); + size_t i, len = hb_parclen( 2 ), iOffset = 0, iIndex = 1; /* Comment including { */ - for( i = 0; i < pLine->item.asString.length; i++ ) + for( i = 0; i < len; i++ ) { - if( pLine->item.asString.value[i] == cDelimiter ) + if( szLine[i] == cDelimiter ) { hb_arraySize( pArray, iIndex ); - hb_storclen( pLine->item.asString.value + iOffset, i - iOffset, 1, iIndex ); + hb_storclen( szLine + iOffset, i - iOffset, 1, iIndex ); iOffset = i + 1; iIndex++; } } - if( iOffset < pLine->item.asString.length - 1 ) + if( iOffset < len - 1 ) { hb_arraySize( pArray, iIndex ); - hb_storclen( pLine->item.asString.value + iOffset, pLine->item.asString.length - iOffset, 1, iIndex ); + hb_storclen( szLine + iOffset, len - iOffset, 1, iIndex ); } }