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:
         [ <exp> ] hb_inLine [ ( [<params,...>] ) ] { [ <c_code> ] } [ <exp> ]
      <c_code> can contain new line characters.
      Nested hb_inLine{} in <params,...> 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

  * harbour/tests/inline_c.prg
    ! replaced direct access to HB_ITEM body by API function calls
This commit is contained in:
Przemyslaw Czerpak
2006-11-10 01:12:49 +00:00
parent 89e25d1371
commit c2b4a94705
11 changed files with 338 additions and 44 deletions

View File

@@ -8,6 +8,63 @@
2002-12-01 13:30 UTC+0100 Foo Bar <foo.bar@foobar.org>
*/
* 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:
[ <exp> ] hb_inLine [ ( [<params,...>] ) ] { [ <c_code> ] } [ <exp> ]
<c_code> can contain new line characters.
Nested hb_inLine{} in <params,...> 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

View File

@@ -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) )

View File

@@ -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 );

View File

@@ -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;

View File

@@ -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",

View File

@@ -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 */

View File

@@ -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 )

View File

@@ -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 )
{

View File

@@ -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;
}

View File

@@ -0,0 +1,26 @@
/*
* $Id$
*/
/*
* Harbour Project source code:
* new Hb_inLine{} test
* compile it using -kcI Harbour compiler switch
*
* Copyright 2006 Przemyslaw Czerpak <druzus / at / priv.onet.pl>
* 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() "

View File

@@ -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 );
}
}