2006-11-15 14:20 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)

* harbour/include/hbapi.h
    + added
         void * pLex;
      member to HB_MACRO structure - it will be necessary for MT safe
      macro parser

  * harbour/include/set.ch
  * harbour/include/hbexprb.c
  * harbour/source/macro/macro.l
  * harbour/source/macro/macro.y
    * indenting, formatting and converting tabs to spaces

  * harbour/include/hbpp.h
  * harbour/source/compiler/ppcomp.c
  * harbour/source/pp/ppcore.c
  * harbour/source/pp/ppgen.c
  * harbour/source/pp/pplib.c
    * make HB_PP_TOKEN structure public for other code and changed
      public PP API to not force including static rules by programs
      which does not need them.
    + added basic API for using PP as lexer
    * divided HB_PP_TOKEN_MACRO to HB_PP_TOKEN_MACROVAR and
      HB_PP_TOKEN_MACROTEXT and mark
         [<keyword>][&<keyword>[.[<nextidchars>]]]+
      as HB_PP_TOKEN_MACROTEXT not pair HB_PP_TOKEN_KEYWORD and
      HB_PP_TOKEN_MACRO
      It allows easier integration PP as (macro)compiler lexer and
      fixes preprocessing [<keyword>][&<keyword>[.[<nextidchars>]]]+
      in some patterns.

  * harbour/utils/hbtest/Makefile
    + added PP library to linked library list

  * harbour/source/macro/macro.y
    + added seaport to use PP as lexer. It's disabled by default and
      can be enabled using by defining HB_PP_MACROLEX. It eliminates
      using FLEX or SIMPLEX lexer in macro compiler. Now it emulates
      the behavior of FLEX lexer because I wanted to minimize the
      modification but in fact because parsed token are freed when
      macro compiler finish its job then we can resolve RT memory
      leaks which apear during parsing wrong expressions. It will be
      enough to drop allocating memory for new terminal symbols and
      using them as is like in compiler. It will also quite nice
      simplify include/hbexpr*.c code and will allow to move some
      functions to COMMON library. I want to make also pure compiler
      code MT safe so I will have to add passing pointer to a structure
      with compiler context just like in macro compiler. It means that
      if we define a structure which will be common to compiler and macro
      compiler with local (not common) data stored in other structure for
      which will will keep only a pointer then we will be able to move most
      of include/hbexpr*.c code to common library. But I do not want to
      make farther modification without consultation without Ryszard.
      Also to make PP default lexer some farther modifications should
      be done in core PP code and include/hbexpr*.c files to not reduce
      the speed. Now using HB_PP_MACROLEX for sure will have to cause
      speed reduction in macro compiler. But if we make necessary
      modifications then we should keep at least the same speed or
      probably reach noticeable better results.
This commit is contained in:
Przemyslaw Czerpak
2006-11-15 13:21:20 +00:00
parent 6fc5b585ec
commit c448973306
12 changed files with 1281 additions and 978 deletions

View File

@@ -8,6 +8,66 @@
2002-12-01 13:30 UTC+0100 Foo Bar <foo.bar@foobar.org>
*/
* old PP functions for backward compatibility:
__PPADDRULE(), __PREPROCESS(), __PP_FREE()
Please note that using this function is not MT safe. They should
work like with old PP code. Using any of this function automatically
forces linking __PP_STDRULES
2006-11-15 14:20 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/include/hbapi.h
+ added
void * pLex;
member to HB_MACRO structure - it will be necessary for MT safe
macro parser
* harbour/include/set.ch
* harbour/include/hbexprb.c
* harbour/source/macro/macro.l
* harbour/source/macro/macro.y
* indenting, formatting and converting tabs to spaces
* harbour/include/hbpp.h
* harbour/source/compiler/ppcomp.c
* harbour/source/pp/ppcore.c
* harbour/source/pp/ppgen.c
* harbour/source/pp/pplib.c
* make HB_PP_TOKEN structure public for other code and changed
public PP API to not force including static rules by programs
which does not need them.
+ added basic API for using PP as lexer
* divided HB_PP_TOKEN_MACRO to HB_PP_TOKEN_MACROVAR and
HB_PP_TOKEN_MACROTEXT and mark
[<keyword>][&<keyword>[.[<nextidchars>]]]+
as HB_PP_TOKEN_MACROTEXT not pair HB_PP_TOKEN_KEYWORD and
HB_PP_TOKEN_MACRO
It allows easier integration PP as (macro)compiler lexer and
fixes preprocessing [<keyword>][&<keyword>[.[<nextidchars>]]]+
in some patterns.
* harbour/utils/hbtest/Makefile
+ added PP library to linked library list
* harbour/source/macro/macro.y
+ added seaport to use PP as lexer. It's disabled by default and
can be enabled using by defining HB_PP_MACROLEX. It eliminates
using FLEX or SIMPLEX lexer in macro compiler. Now it emulates
the behavior of FLEX lexer because I wanted to minimize the
modification but in fact because parsed token are freed when
macro compiler finish its job then we can resolve RT memory
leaks which apear during parsing wrong expressions. It will be
enough to drop allocating memory for new terminal symbols and
using them as is like in compiler. It will also quite nice
simplify include/hbexpr*.c code and will allow to move some
functions to COMMON library. I want to make also pure compiler
code MT safe so I will have to add passing pointer to a structure
with compiler context just like in macro compiler. It means that
if we define a structure which will be common to compiler and macro
compiler with local (not common) data stored in other structure for
which will will keep only a pointer then we will be able to move most
of include/hbexpr*.c code to common library. But I do not want to
make farther modification without consultation without Ryszard.
Also to make PP default lexer some farther modifications should
be done in core PP code and include/hbexpr*.c files to not reduce
the speed. Now using HB_PP_MACROLEX for sure will have to cause
speed reduction in macro compiler. But if we make necessary

View File

@@ -804,6 +804,7 @@ typedef struct HB_MACRO_ /* a macro compiled pcode container */
HB_ITEM_PTR pError; /* error object returned from the parser */
ULONG supported; /* various flags for supported capabilities */
int FlexState; /* internal flex state during parsing */
void * pLex; /* lexer buffer pointer */
HB_PCODE_INFO_PTR pCodeInfo; /* pointer to pcode buffer and info */
void * pParseInfo; /* data needed by the parser - it should be 'void *' to allow different implementation of macr compiler */
USHORT uiNameLen; /* the maximum symbol name length */

File diff suppressed because it is too large Load Diff

View File

@@ -113,44 +113,6 @@ typedef HB_PP_SWITCH_FUNC_( HB_PP_SWITCH_FUNC );
typedef HB_PP_SWITCH_FUNC * PHB_PP_SWITCH_FUNC;
#ifdef _HB_PP_INTERNAL
/* default maximum number of translations */
#define HB_PP_MAX_CYCLES 4096
/* maximum number of single token translations, in Clipper it's 18 + number
of used rules, we will use also constant but increased by total number
of rules of given type: define, [x]translate, [x]command */
#define HB_PP_MAX_REPATS 128
/* Clipper allows only 16 nested includes */
#define HB_PP_MAX_INCLUDED_FILES 64
/* comparision modes */
#define HB_PP_CMP_ADDR 0 /* compare token addresses */
#define HB_PP_CMP_STD 1 /* standard comparison, ignore the case of the characters */
#define HB_PP_CMP_DBASE 2 /* dbase keyword comparison (accepts at least four character shortcuts) ignore the case of the characters */
#define HB_PP_CMP_CASE 3 /* case sensitive comparison */
#define HB_PP_CMP_MODE(t) ( (t) & 0xff )
#define HB_PP_STD_RULE 0x8000
/* conditional compilation */
#define HB_PP_COND_ELSE 1 /* preprocessing and output stopped until corresponding #else */
#define HB_PP_COND_DISABLE 2 /* preprocessing and output stopped until corresponding #endif(s) */
/* operation precedence for #if calculation */
#define HB_PP_PREC_NUL 0
#define HB_PP_PREC_NOT 1
#define HB_PP_PREC_LOG 2
#define HB_PP_PREC_REL 3
#define HB_PP_PREC_BIT 4
#define HB_PP_PREC_PLUS 5
#define HB_PP_PREC_MULT 6
#define HB_PP_PREC_NEG 7
/* preprocessor tokens */
#define HB_PP_TOKEN_NUL 0
@@ -173,17 +135,18 @@ typedef HB_PP_SWITCH_FUNC * PHB_PP_SWITCH_FUNC;
/* keywords, pseudo keywords and PP only tokens */
#define HB_PP_TOKEN_KEYWORD 21
#define HB_PP_TOKEN_MACRO 22
#define HB_PP_TOKEN_TEXT 23
#define HB_PP_TOKEN_OTHER 24 /* non keyword, text, or operator character */
#define HB_PP_TOKEN_BACKSLASH 25 /* "\\" */
#define HB_PP_TOKEN_PIPE 26 /* "|" */
#define HB_PP_TOKEN_DOT 27 /* "." */
#define HB_PP_TOKEN_COMMA 28 /* "," */
#define HB_PP_TOKEN_EOC 29 /* ";" */
#define HB_PP_TOKEN_EOL 30 /* "\n" */
#define HB_PP_TOKEN_HASH 31 /* "\n" */
#define HB_PP_TOKEN_DIRECTIVE 32 /* direct # directive first token */
#define HB_PP_TOKEN_MACROVAR 22
#define HB_PP_TOKEN_MACROTEXT 23
#define HB_PP_TOKEN_TEXT 24
#define HB_PP_TOKEN_OTHER 25 /* non keyword, text, or operator character */
#define HB_PP_TOKEN_BACKSLASH 26 /* "\\" */
#define HB_PP_TOKEN_PIPE 27 /* "|" */
#define HB_PP_TOKEN_DOT 28 /* "." */
#define HB_PP_TOKEN_COMMA 29 /* "," */
#define HB_PP_TOKEN_EOC 30 /* ";" */
#define HB_PP_TOKEN_EOL 31 /* "\n" */
#define HB_PP_TOKEN_HASH 32 /* "#" */
#define HB_PP_TOKEN_DIRECTIVE 33 /* direct # directive first token */
/* constant values */
#define HB_PP_TOKEN_STRING 41
@@ -231,18 +194,69 @@ typedef HB_PP_SWITCH_FUNC * PHB_PP_SWITCH_FUNC;
#define HB_PP_TOKEN_MOD 84
#define HB_PP_TOKEN_POWER 85
#define HB_PP_TOKEN_TYPE(t) ( (t) & 0xff )
typedef struct _HB_PP_TOKEN
{
struct _HB_PP_TOKEN * pNext; /* next token pointer */
struct _HB_PP_TOKEN * pMTokens; /* restrict or optional marker token(s) */
char * value; /* token value */
USHORT len; /* token value length */
USHORT spaces; /* leading spaces for stringify */
USHORT type; /* token type, see HB_PP_TOKEN_* */
USHORT index; /* index to match marker or 0 */
}
HB_PP_TOKEN, * PHB_PP_TOKEN;
#ifdef _HB_PP_INTERNAL
/* default maximum number of translations */
#define HB_PP_MAX_CYCLES 4096
/* maximum number of single token translations, in Clipper it's 18 + number
of used rules, we will use also constant but increased by total number
of rules of given type: define, [x]translate, [x]command */
#define HB_PP_MAX_REPATS 128
/* Clipper allows only 16 nested includes */
#define HB_PP_MAX_INCLUDED_FILES 64
/* comparision modes */
#define HB_PP_CMP_ADDR 0 /* compare token addresses */
#define HB_PP_CMP_STD 1 /* standard comparison, ignore the case of the characters */
#define HB_PP_CMP_DBASE 2 /* dbase keyword comparison (accepts at least four character shortcuts) ignore the case of the characters */
#define HB_PP_CMP_CASE 3 /* case sensitive comparison */
#define HB_PP_CMP_MODE(t) ( (t) & 0xff )
#define HB_PP_STD_RULE 0x8000
/* conditional compilation */
#define HB_PP_COND_ELSE 1 /* preprocessing and output stopped until corresponding #else */
#define HB_PP_COND_DISABLE 2 /* preprocessing and output stopped until corresponding #endif(s) */
/* operation precedence for #if calculation */
#define HB_PP_PREC_NUL 0
#define HB_PP_PREC_NOT 1
#define HB_PP_PREC_LOG 2
#define HB_PP_PREC_REL 3
#define HB_PP_PREC_BIT 4
#define HB_PP_PREC_PLUS 5
#define HB_PP_PREC_MULT 6
#define HB_PP_PREC_NEG 7
/* bitfields */
//#define HB_PP_TOKEN_UNARY 0x0100
//#define HB_PP_TOKEN_BINARY 0x0200
//#define HB_PP_TOKEN_JOINABLE 0x0400
/* #define HB_PP_TOKEN_UNARY 0x0100 */
/* #define HB_PP_TOKEN_BINARY 0x0200 */
/* #define HB_PP_TOKEN_JOINABLE 0x0400 */
#define HB_PP_TOKEN_MATCHMARKER 0x2000
#define HB_PP_TOKEN_STATIC 0x4000
#define HB_PP_TOKEN_PREDEFINED 0x8000
#define HB_PP_TOKEN_SETTYPE(t,n) do{ (t)->type = ( (t)->type & 0xff00 ) | (n); } while(0)
#define HB_PP_TOKEN_TYPE(t) ( (t) & 0xff )
#define HB_PP_TOKEN_ALLOC(t) ( ( (t) & HB_PP_TOKEN_STATIC ) == 0 )
#define HB_PP_TOKEN_ISPREDEF(t) ( ( (t)->type & HB_PP_TOKEN_PREDEFINED ) != 0 )
@@ -283,7 +297,8 @@ typedef HB_PP_SWITCH_FUNC * PHB_PP_SWITCH_FUNC;
#define HB_PP_TOKEN_CANJOIN(t) ( ! HB_PP_TOKEN_CLOSE_BR(t) && \
HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_KEYWORD && \
HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_MACRO && \
HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_MACROVAR && \
HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_MACROTEXT && \
HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_TEXT && \
HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_STRING && \
HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_NUMBER && \
@@ -362,7 +377,8 @@ typedef HB_PP_SWITCH_FUNC * PHB_PP_SWITCH_FUNC;
#endif
#define HB_PP_TOKEN_ISEXPVAL(t) ( HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_KEYWORD || \
HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_MACRO || \
HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_MACROVAR || \
HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_MACROTEXT || \
HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_STRING || \
HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_NUMBER || \
HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_DATE )
@@ -375,7 +391,8 @@ typedef HB_PP_SWITCH_FUNC * PHB_PP_SWITCH_FUNC;
are checking for HB_PP_TOKEN_NUL in this macro */
#define HB_PP_TOKEN_CANQUOTE(t) ( HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_NUL && \
HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_KEYWORD && \
HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_MACRO && \
HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_MACROVAR && \
HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_MACROTEXT && \
HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_RIGHT_PB && \
HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_RIGHT_SB && \
HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_RIGHT_CB )
@@ -386,7 +403,8 @@ typedef HB_PP_SWITCH_FUNC * PHB_PP_SWITCH_FUNC;
similar extensions in the future */
#define HB_PP_TOKEN_CANQUOTE(t) ( HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_NUL && \
HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_KEYWORD && \
HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_MACRO && \
HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_MACROVAR && \
HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_MACROTEXT && \
HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_RIGHT_PB && \
HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_RIGHT_SB && \
HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_RIGHT_CB && \
@@ -417,19 +435,6 @@ typedef HB_PP_SWITCH_FUNC * PHB_PP_SWITCH_FUNC;
( (c) >= 'a' && (c) <= 'z' ) || (c) == '_' )
#define HB_PP_ISNEXTIDCHAR(c) ( HB_PP_ISFIRSTIDCHAR(c) || HB_PP_ISDIGIT(c) )
typedef struct _HB_PP_TOKEN
{
struct _HB_PP_TOKEN * pNext; /* next token pointer */
struct _HB_PP_TOKEN * pMTokens; /* restrict or optional marker token(s) */
char * value; /* token value */
USHORT len; /* token value length */
USHORT spaces; /* leading spaces for stringify */
USHORT type; /* token type, see HB_PP_TOKEN_* */
USHORT index; /* index to match marker or 0 */
}
HB_PP_TOKEN, * PHB_PP_TOKEN;
typedef struct _HB_PP_RESULT
{
struct _HB_PP_RESULT * pNext;
@@ -594,7 +599,6 @@ HB_PP_STATE, * PHB_PP_STATE;
extern void hb_pp_initRules( PHB_PP_RULE * pRulesPtr, int * piRules,
const HB_PP_DEFRULE pDefRules[], int iDefRules );
extern void hb_pp_initStaticRules( PHB_PP_STATE pState );
#else
@@ -604,13 +608,16 @@ typedef void * PHB_PP_STATE;
/* public functions */
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_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_init( PHB_PP_STATE pState, 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_INLINE_FUNC pInLineFunc,
PHB_PP_SWITCH_FUNC pSwitchFunc );
extern void hb_pp_initDynDefines( PHB_PP_STATE pState );
extern void hb_pp_readRules( PHB_PP_STATE pState, char * szRulesFile );
extern void hb_pp_setStdRules( 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 );
@@ -624,6 +631,10 @@ extern char * hb_pp_parseLine( PHB_PP_STATE pState, char * pLine, ULONG * pulLen
extern void hb_pp_addDefine( PHB_PP_STATE pState, char * szDefName, char * szDefValue );
extern void hb_pp_delDefine( PHB_PP_STATE pState, char * szDefName );
extern void hb_pp_tokenUpper( PHB_PP_TOKEN pToken );
extern PHB_PP_STATE hb_pp_lexNew( char * pString, ULONG ulLen );
extern PHB_PP_TOKEN hb_pp_lex( PHB_PP_STATE pState );
HB_EXTERN_END
#endif /* HB_PP_H_ */

View File

@@ -124,7 +124,7 @@
#define _SET_FORCEOPT 107 /* Harbour extension */
#define _SET_DBFLOCKSCHEME 108 /* Harbour extension */
#define _SET_DEFEXTENSIONS 109 /* Harbour extension */
#define HB_SET_BASE 100
#define HB_SET_COUNT 10

View File

@@ -277,12 +277,24 @@ void hb_pp_SetRules( BOOL fQuiet, int argc, char * argv[] )
s_pp_state = hb_pp_new();
if( s_pp_state )
{
hb_pp_init( s_pp_state, szStdCh, fQuiet,
hb_pp_init( s_pp_state, fQuiet,
hb_pp_IncludeOpen, hb_pp_IncludeClose,
hb_pp_ErrorGen, NULL, hb_pp_PragmaDump,
HB_COMP_ISSUPPORTED( HB_COMPFLAG_HB_INLINE_PP ) ?
hb_pp_hb_inLine : NULL, hb_pp_CompilerSwitch );
if( !szStdCh )
hb_pp_setStdRules( s_pp_state );
else if( *szStdCh )
hb_pp_readRules( s_pp_state, szStdCh );
else
{
printf( "Standard command definitions excluded.\n" );
fflush( stdout );
}
hb_pp_initDynDefines( s_pp_state );
/* Add /D and /undef: command line or envvar defines */
hb_compChkDefines( argc, argv );

View File

@@ -235,15 +235,15 @@ MacroTxt ({MacroVar}|{MacroEnd}|{MacroId})+
[\=\+\-\*\/\%\$\,\|\#\&\.\:\<\>\@] { pMacro->FlexState = SEPARATOR; return yytext[ 0 ]; }
[\]\}\)] { pMacro->FlexState = LOOKUP; return yytext[ 0 ]; }
[\x00-\x1F] return yytext[ 0 ]; /* see below */
[\~\`\?\_\\] return yytext[ 0 ]; /* see below */
[\x7F-\xFF] {
/* This have to be the last rule - any nonstandard and unhandled
* characters should go to grammar analyser instead of printing it
* on stdout.
*/
return yytext[ 0 ];
}
[\x00-\x1F] return yytext[ 0 ]; /* see below */
[\~\`\?\_\\] return yytext[ 0 ]; /* see below */
[\x7F-\xFF] {
/* This have to be the last rule - any nonstandard and
* unhandled characters should go to grammar analyser
* instead of printing it on stdout.
*/
return yytext[ 0 ];
}
%{
/* ************************************************************************ */
@@ -261,13 +261,12 @@ MacroTxt ({MacroVar}|{MacroEnd}|{MacroId})+
yylval_ptr->valDouble.dNumber = dNumber;
yylval_ptr->valDouble.bDec = iDec;
yylval_ptr->valDouble.bWidth = iWidth;
yylval_ptr->valDouble.szValue = yytext;
return NUM_DOUBLE;
}
else
{
yylval_ptr->valLong.lNumber = lNumber;
yylval_ptr->valLong.szValue = yytext;
yylval_ptr->valLong.bWidth = iWidth;
return NUM_LONG;
}
}

View File

@@ -65,6 +65,7 @@
#include "hbmacro.h"
#include "hbcomp.h"
#include "hbdate.h"
#include "hbpp.h"
/* Compile using: bison -d -p hb_comp macro.y */
@@ -103,7 +104,7 @@
#undef YYLEX_PARAM
#define YYLEX_PARAM ( (HB_MACRO_PTR)YYPARSE_PARAM ) /* additional parameter passed to yylex */
extern int yyparse( void * ); /* to make happy some purist compiler */
extern int yyparse( void * ); /* to make happy some purist compiler */
extern void * hb_compFlexNew( HB_MACRO_PTR );
extern void hb_compFlexDelete( void * );
@@ -119,7 +120,9 @@ extern void yyerror( char * ); /* parsing error management function */
#define HB_MACRO_IFENABLED( pSet, pExpr, flag ) \
if( HB_MACRO_DATA->supported & (flag) ) \
{ pSet = (pExpr); }\
{ \
pSet = (pExpr); \
}\
else \
{ \
YYABORT; \
@@ -129,29 +132,26 @@ extern void yyerror( char * ); /* parsing error management function */
%union /* special structure used by lex and yacc to share info */
{
char * string; /* to hold a string returned by lex */
int iNumber; /* to hold a temporary integer number */
HB_LONG lNumber; /* to hold a temporary long number */
char * string; /* to hold a string returned by lex */
int iNumber; /* to hold a temporary integer number */
HB_LONG lNumber; /* to hold a temporary long number */
void * pVoid; /* to hold any memory structure we may need */
HB_EXPR_PTR asExpr;
struct
{
int iNumber; /* to hold a number returned by lex */
char * szValue;
int iNumber; /* to hold a number returned by lex */
} valInteger;
struct
{
HB_LONG lNumber; /* to hold a long number returned by lex */
char * szValue;
HB_LONG lNumber; /* to hold a long number returned by lex */
UCHAR bWidth; /* to hold the width of the value */
} valLong;
struct
{
double dNumber; /* to hold a double number returned by lex */
/* NOTE: Intentionally using "unsigned char" instead of "BYTE" */
unsigned char bWidth; /* to hold the width of the value */
unsigned char bDec; /* to hold the number of decimal points in the value */
char * szValue;
double dNumber; /* to hold a double number returned by lex */
UCHAR bWidth; /* to hold the width of the value */
UCHAR bDec; /* to hold the number of decimal points in the value */
} valDouble;
HB_EXPR_PTR asExpr;
void * pVoid; /* to hold any memory structure we may need */
};
%{
@@ -176,9 +176,9 @@ int yylex( YYSTYPE *, HB_MACRO_PTR );
/*the lowest precedence*/
/*postincrement and postdecrement*/
%left POST
%left POST
/*assigment - from right to left*/
%right INASSIGN
%right INASSIGN
%right PLUSEQ MINUSEQ
%right MULTEQ DIVEQ MODEQ
%right EXPEQ
@@ -192,7 +192,7 @@ int yylex( YYSTYPE *, HB_MACRO_PTR );
%right '+' '-'
%right '*' '/' '%'
%right POWER
%right UNARY
%right UNARY
/*preincrement and predecrement*/
%right PRE
/*special operators*/
@@ -260,17 +260,17 @@ Main : Expression '\n' {
hb_compExprGenPop( $1, HB_MACRO_PARAM );
hb_compGenPCode1( HB_P_ENDPROC, HB_MACRO_PARAM );
}
| Expression error {
HB_TRACE(HB_TR_DEBUG, ("macro -> invalid expression: %s", HB_MACRO_DATA->string));
hb_macroError( EG_SYNTAX, HB_MACRO_PARAM );
YYABORT;
}
| Expression error {
HB_TRACE(HB_TR_DEBUG, ("macro -> invalid expression: %s", HB_MACRO_DATA->string));
hb_macroError( EG_SYNTAX, HB_MACRO_PARAM );
YYABORT;
}
| error {
HB_TRACE(HB_TR_DEBUG, ("macro -> invalid syntax: %s", HB_MACRO_DATA->string));
hb_macroError( EG_SYNTAX, HB_MACRO_PARAM );
YYABORT;
}
;
HB_TRACE(HB_TR_DEBUG, ("macro -> invalid syntax: %s", HB_MACRO_DATA->string));
hb_macroError( EG_SYNTAX, HB_MACRO_PARAM );
YYABORT;
}
;
/* Numeric values
*/
@@ -278,55 +278,55 @@ NumValue : NUM_DOUBLE { $$ = hb_compExprNewDouble( $1.dNumber, $1.bWidth,
| NUM_LONG { $$ = hb_compExprNewLong( $1.lNumber ); }
;
DateValue : NUM_DATE { $$ = hb_compExprNewDate( $1.lNumber ); }
DateValue : NUM_DATE { $$ = hb_compExprNewDate( $1.lNumber ); }
;
NumAlias : NUM_LONG ALIASOP { $$ = hb_compExprNewLong( $1.lNumber ); }
;
NumAlias : NUM_LONG ALIASOP { $$ = hb_compExprNewLong( $1.lNumber ); }
;
/* NIL value
*/
NilValue : NIL { $$ = hb_compExprNewNil(); }
;
NilValue : NIL { $$ = hb_compExprNewNil(); }
;
/* Literal string value
*/
LiteralValue : LITERAL { $$ = hb_compExprNewString( $1, strlen($1) ); }
;
LiteralValue : LITERAL { $$ = hb_compExprNewString( $1, strlen($1) ); }
;
/* Logical value
*/
Logical : TRUEVALUE { $$ = hb_compExprNewLogical( TRUE ); }
| FALSEVALUE { $$ = hb_compExprNewLogical( FALSE ); }
Logical : TRUEVALUE { $$ = hb_compExprNewLogical( TRUE ); }
| FALSEVALUE { $$ = hb_compExprNewLogical( FALSE ); }
;
/* SELF value and expressions
*/
SelfValue : SELF { $$ = hb_compExprNewSelf(); }
;
SelfValue : SELF { $$ = hb_compExprNewSelf(); }
;
/* Literal array
*/
Array : '{' ElemList '}' { $$ = hb_compExprNewArray( $2, HB_MACRO_PARAM ); }
Array : '{' ElemList '}' { $$ = hb_compExprNewArray( $2, HB_MACRO_PARAM ); }
;
/* Literal array access
*/
ArrayAt : Array ArrayIndex { $$ = $2; }
;
ArrayAt : Array ArrayIndex { $$ = $2; }
;
/* Variables
*/
Variable : IDENTIFIER { $$ = hb_compExprNewVar( $1 ); }
;
Variable : IDENTIFIER { $$ = hb_compExprNewVar( $1 ); }
;
VarAlias : IDENTIFIER ALIASOP { $$ = hb_compExprNewAlias( $1 ); }
;
VarAlias : IDENTIFIER ALIASOP { $$ = hb_compExprNewAlias( $1 ); }
;
/* Macro variables - this can signal compilation errors
*/
MacroVar : MACROVAR { $$ = hb_compExprNewMacro( NULL, '&', $1 );
HB_MACRO_CHECK( $$ );
MacroVar : MACROVAR { $$ = hb_compExprNewMacro( NULL, '&', $1 );
HB_MACRO_CHECK( $$ );
}
| MACROTEXT { ULONG ulLen = strlen( $1 );
char * szVarName = hb_macroTextSubst( $1, &ulLen );
@@ -346,18 +346,18 @@ MacroVar : MACROVAR { $$ = hb_compExprNewMacro( NULL, '&', $1 );
YYABORT;
}
}
;
;
MacroVarAlias : MacroVar ALIASOP { $$ = $1; }
;
;
/* Macro expressions
*/
MacroExpr : '&' PareExpList { $$ = hb_compExprNewMacro( $2, 0, NULL ); }
;
MacroExpr : '&' PareExpList { $$ = hb_compExprNewMacro( $2, 0, NULL ); }
;
MacroExprAlias : MacroExpr ALIASOP { $$ = $1; }
;
MacroExprAlias : MacroExpr ALIASOP { $$ = $1; }
;
/* Aliased variables
*/
@@ -429,7 +429,7 @@ FunCall : IDENTIFIER '(' ArgList ')' { $$ = hb_compExprNewFunCall( hb_compE
| MacroVar '(' ArgList ')' { $$ = hb_compExprNewFunCall( $1, $3, HB_MACRO_PARAM );
HB_MACRO_CHECK( $$ );
}
;
;
ArgList : Argument { $$ = hb_compExprNewArgList( $1 ); }
| ArgList ',' Argument { $$ = hb_compExprAddListExpr( $1, $3 ); }
@@ -468,7 +468,7 @@ ObjectData : NumValue ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3,
/* Object's method
*/
ObjectMethod : ObjectData '(' ArgList ')' { $$ = hb_compExprNewMethodCall( $1, $3 ); }
;
;
SimpleExpression :
NumValue
@@ -498,11 +498,11 @@ SimpleExpression :
| ExprMath { $$ = $1; }
| ExprBool { $$ = $1; }
| ExprRelation { $$ = $1; }
;
;
Expression : SimpleExpression { $$ = $1; HB_MACRO_CHECK( $$ ); }
| PareExpList { $$ = $1; HB_MACRO_CHECK( $$ ); }
;
;
RootParamList : EmptyExpression ',' {
if( !(HB_MACRO_DATA->Flags & HB_MACRO_GEN_LIST) )
@@ -513,18 +513,19 @@ RootParamList : EmptyExpression ',' {
}
}
EmptyExpression {
HB_MACRO_DATA->iListElements = 1;
$$ = hb_compExprAddListExpr( ( HB_MACRO_DATA->Flags & HB_MACRO_GEN_PARE ) ? hb_compExprNewList( $1 ) : hb_compExprNewArgList( $1 ), $4 );
HB_MACRO_DATA->iListElements = 1;
$$ = hb_compExprAddListExpr( ( HB_MACRO_DATA->Flags & HB_MACRO_GEN_PARE ) ? hb_compExprNewList( $1 ) : hb_compExprNewArgList( $1 ), $4 );
}
;
AsParamList : RootParamList { $$ = $1; }
| AsParamList ',' EmptyExpression { HB_MACRO_DATA->iListElements++; $$ = hb_compExprAddListExpr( $1, $3 ); }
;
AsParamList : RootParamList { $$ = $1; }
| AsParamList ',' EmptyExpression { HB_MACRO_DATA->iListElements++;
$$ = hb_compExprAddListExpr( $1, $3 ); }
;
EmptyExpression: /* nothing => nil */ { $$ = hb_compExprNewEmpty(); }
| Expression
;
| Expression
;
/* NOTE: PostOp can be used in one context only - it uses $0 rule
* (the rule that stands before PostOp)
@@ -779,8 +780,8 @@ BlockExpList : Expression { $$ = hb_compExprAddCodeblockExpr( $<a
/* NOTE: This is really not needed however it allows the use of $-2 item
* in BlockExpList to refer the same rule defined in Codeblock
*/
BlockNoVar : /* empty list */ { $$ = NULL; }
;
BlockNoVar : /* empty list */ { $$ = NULL; }
;
BlockVarList : IDENTIFIER { $$ = hb_compExprCBVarAdd( $<asExpr>0, $1, HB_MACRO_PARAM ); }
| BlockVarList ',' IDENTIFIER { $$ = hb_compExprCBVarAdd( $<asExpr>0, $3, HB_MACRO_PARAM ); HB_MACRO_CHECK( $$ ); }
@@ -788,24 +789,24 @@ BlockVarList : IDENTIFIER { $$ = hb_compExprCBVarAdd( $<asExpr>0
ExpList : '(' EmptyExpression { $$ = hb_compExprNewList( $2 ); }
| ExpList ',' EmptyExpression { $$ = hb_compExprAddListExpr( $1, $3 ); }
;
;
PareExpList : ExpList ')' { $$ = $1; }
;
;
PareExpListAlias : PareExpList ALIASOP { $$ = $1; }
;
PareExpListAlias : PareExpList ALIASOP { $$ = $1; }
;
IfInline : IIF '(' Expression ',' EmptyExpression ','
{ $<asExpr>$ = hb_compExprAddListExpr( hb_compExprNewList( $3 ), $5 ); }
EmptyExpression ')'
{ $$ = hb_compExprNewIIF( hb_compExprAddListExpr( $<asExpr>7, $8 ) ); }
IfInline : IIF '(' Expression ',' EmptyExpression ','
{ $<asExpr>$ = hb_compExprAddListExpr( hb_compExprNewList( $3 ), $5 ); }
EmptyExpression ')'
{ $$ = hb_compExprNewIIF( hb_compExprAddListExpr( $<asExpr>7, $8 ) ); }
| IF '(' Expression ',' EmptyExpression ','
{ $<asExpr>$ = hb_compExprAddListExpr( hb_compExprNewList( $3 ), $5 ); }
EmptyExpression ')'
{ $$ = hb_compExprNewIIF( hb_compExprAddListExpr( $<asExpr>7, $8 ) ); }
;
| IF '(' Expression ',' EmptyExpression ','
{ $<asExpr>$ = hb_compExprAddListExpr( hb_compExprNewList( $3 ), $5 ); }
EmptyExpression ')'
{ $$ = hb_compExprNewIIF( hb_compExprAddListExpr( $<asExpr>7, $8 ) ); }
;
%%
@@ -819,6 +820,17 @@ IfInline : IIF '(' Expression ',' EmptyExpression ','
** ------------------------------------------------------------------------ **
*/
void yyerror( char * s )
{
HB_SYMBOL_UNUSED( s );
}
/* ************************************************************************* */
/* #define HB_PP_MACROLEX */
#ifndef HB_PP_MACROLEX
int hb_macroYYParse( HB_MACRO_PTR pMacro )
{
int iResult;
@@ -836,10 +848,161 @@ int hb_macroYYParse( HB_MACRO_PTR pMacro )
return iResult;
}
/* ************************************************************************* */
#else
void yyerror( char * s )
int hb_macroYYParse( HB_MACRO_PTR pMacro )
{
HB_SYMBOL_UNUSED( s );
int iResult;
pMacro->pLex = ( void * ) hb_pp_lexNew( pMacro->string, pMacro->length );
if( pMacro->pLex )
{
pMacro->status = HB_MACRO_CONT;
/* NOTE: bison requires (void *) pointer */
iResult = yyparse( ( void * ) pMacro );
hb_pp_free( ( PHB_PP_STATE ) pMacro->pLex );
pMacro->pLex = NULL;
}
else
iResult = HB_MACRO_FAILURE;
return iResult;
}
int hb_complex( YYSTYPE *yylval_ptr, HB_MACRO_PTR pMacro )
{
PHB_PP_TOKEN pToken = hb_pp_lex( ( PHB_PP_STATE ) pMacro->pLex );
if( !pToken )
return 0;
switch( HB_PP_TOKEN_TYPE( pToken->type ) )
{
case HB_PP_TOKEN_KEYWORD:
if( pToken->len >= 4 && pToken->len <= 6 &&
( hb_strnicmp( "_FILED", pToken->value, pToken->len ) == 0 ||
hb_strnicmp( "FILED", pToken->value, pToken->len ) == 0 ) )
return FIELD;
else if( pToken->len == 3 && hb_stricmp( "IIF", pToken->value ) == 0 )
return IIF;
else if( pToken->len == 2 && hb_stricmp( "IF", pToken->value ) == 0 )
return IIF;
else if( pToken->len == 3 && hb_stricmp( "NIL", pToken->value ) == 0 )
return NIL;
hb_pp_tokenUpper( pToken );
yylval_ptr->string = hb_strdup( pToken->value );
return IDENTIFIER;
case HB_PP_TOKEN_MACROVAR:
hb_pp_tokenUpper( pToken );
yylval_ptr->string = hb_strdup( pToken->value );
return MACROVAR;
case HB_PP_TOKEN_MACROTEXT:
hb_pp_tokenUpper( pToken );
yylval_ptr->string = hb_strdup( pToken->value );
return MACROTEXT;
case HB_PP_TOKEN_NUMBER:
{
HB_LONG lNumber;
double dNumber;
int iDec, iWidth;
if( hb_compStrToNum( pToken->value, &lNumber, &dNumber, &iDec, &iWidth ) )
{
yylval_ptr->valDouble.dNumber = dNumber;
yylval_ptr->valDouble.bDec = ( UCHAR ) iDec;
yylval_ptr->valDouble.bWidth = ( UCHAR ) iWidth;
return NUM_DOUBLE;
}
else
{
yylval_ptr->valLong.lNumber = lNumber;
yylval_ptr->valLong.bWidth = ( UCHAR ) iWidth;
return NUM_LONG;
}
}
case HB_PP_TOKEN_DATE:
if( pToken->len == 10 )
{
int year, month, day;
hb_dateStrGet( pToken->value + 2, &year, &month, &day );
yylval_ptr->valLong.lNumber = hb_dateEncode( year, month, day );
}
else
yylval_ptr->valLong.lNumber = 0;
return NUM_DATE;
case HB_PP_TOKEN_STRING:
yylval_ptr->string = hb_strdup( pToken->value );
return LITERAL;
case HB_PP_TOKEN_LOGICAL:
return pToken->value[ 1 ] == 'Y' ? TRUEVALUE : FALSEVALUE;
case HB_PP_TOKEN_HASH:
case HB_PP_TOKEN_DIRECTIVE:
return NE1;
case HB_PP_TOKEN_NE:
return NE2;
case HB_PP_TOKEN_ASSIGN:
return INASSIGN;
case HB_PP_TOKEN_EQUAL:
return EQ;
case HB_PP_TOKEN_INC:
return INC;
case HB_PP_TOKEN_DEC:
return DEC;
case HB_PP_TOKEN_ALIAS:
return ALIASOP;
case HB_PP_TOKEN_LE:
return LE;
case HB_PP_TOKEN_GE:
return GE;
case HB_PP_TOKEN_PLUSEQ:
return PLUSEQ;
case HB_PP_TOKEN_MINUSEQ:
return MINUSEQ;
case HB_PP_TOKEN_MULTEQ:
return MULTEQ;
case HB_PP_TOKEN_DIVEQ:
return DIVEQ;
case HB_PP_TOKEN_MODEQ:
return MODEQ;
case HB_PP_TOKEN_EXPEQ:
return EXPEQ;
case HB_PP_TOKEN_POWER:
return POWER;
case HB_PP_TOKEN_AND:
return AND;
case HB_PP_TOKEN_OR:
return OR;
case HB_PP_TOKEN_NOT:
return NOT;
default:
return pToken->value[ 0 ];
}
}
#endif /* HB_PP_MACROLEX */

View File

@@ -1009,9 +1009,27 @@ static void hb_pp_getLine( PHB_PP_STATE pState )
}
else
{
if( pState->pInLineFunc &&
pState->iInLineState == HB_PP_INLINE_OFF &&
ul == 9 && hb_strnicmp( "hb_inLine", pBuffer, 9 ) == 0 )
if( ul < ulLen && pBuffer[ ul ] == '&' )
{
/*
* [<keyword>][&<keyword>[.[<nextidchars>]]]+ is a single
* token in Clipper and this fact is important in later
* preprocessing so we have to replicate it
*/
while( ulLen - ul > 1 && pBuffer[ ul ] == '&' &&
HB_PP_ISFIRSTIDCHAR( pBuffer[ ul + 1 ] ) )
{
while( ++ul < ulLen && HB_PP_ISNEXTIDCHAR( pBuffer[ ul ] ) );
if( ul < ulLen && pBuffer[ ul ] == '.' )
while( ++ul < ulLen && HB_PP_ISNEXTIDCHAR( pBuffer[ ul ] ) );
}
if( ul < ulLen && pBuffer[ ul ] == '&' )
++ul;
hb_pp_tokenAddNext( pState, pBuffer, ul, HB_PP_TOKEN_MACROTEXT );
}
else 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 );
@@ -1090,21 +1108,28 @@ static void hb_pp_getLine( PHB_PP_STATE pState )
}
else if( ch == '&' && ulLen > 1 && HB_PP_ISFIRSTIDCHAR( pBuffer[ 1 ] ) )
{
int iParts = 0;
/*
* [&<keyword>[.[<nextidchars>]]]+ is a single token in Clipper
* [<keyword>][&<keyword>[.[<nextidchars>]]]+ is a single token in Clipper
* and this fact is important in later preprocessing so we have
* to replicate it
*/
while( ulLen - ul > 1 && pBuffer[ ul ] == '&' &&
HB_PP_ISFIRSTIDCHAR( pBuffer[ ul + 1 ] ) )
{
++iParts;
while( ++ul < ulLen && HB_PP_ISNEXTIDCHAR( pBuffer[ ul ] ) );
if( ul < ulLen && pBuffer[ ul ] == '.' )
while( ++ul < ulLen && HB_PP_ISNEXTIDCHAR( pBuffer[ ul ] ) );
while( ++ul < ulLen && HB_PP_ISNEXTIDCHAR( pBuffer[ ul ] ) )
++iParts;
}
if( ul < ulLen && pBuffer[ ul ] == '&' )
{
++iParts;
++ul;
hb_pp_tokenAddNext( pState, pBuffer, ul, HB_PP_TOKEN_MACRO );
}
hb_pp_tokenAddNext( pState, pBuffer, ul, iParts == 1 ?
HB_PP_TOKEN_MACROVAR : HB_PP_TOKEN_MACROTEXT );
}
else if( ch == '{' && !pState->fCanNextLine &&
( pState->iInLineState == HB_PP_INLINE_BODY ||
@@ -3013,12 +3038,14 @@ static BOOL hb_pp_tokenMatch( PHB_PP_TOKEN pMatch, PHB_PP_TOKEN * pTokenPtr,
else if( HB_PP_TOKEN_TYPE( pRestrict->type ) == HB_PP_TOKEN_AMPERSAND &&
( !pRestrict->pNext ||
HB_PP_TOKEN_TYPE( pRestrict->pNext->type ) == HB_PP_TOKEN_COMMA ) &&
( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_MACRO ||
( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_MACROVAR ||
HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_MACROTEXT ||
( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_AMPERSAND &&
pToken->pNext &&
HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_LEFT_PB ) ) )
{
if( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_MACRO )
if( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_MACROVAR ||
HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_MACROTEXT )
{
* pTokenPtr = pToken->pNext;
}
@@ -3288,16 +3315,14 @@ static PHB_PP_TOKEN * hb_pp_matchResultLstAdd( PHB_PP_STATE pState,
if( !fBlock )
hb_pp_tokenAdd( &pResultPtr, "}", 1, 0, HB_PP_TOKEN_RIGHT_CB | HB_PP_TOKEN_STATIC );
}
else if( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_MACRO &&
else if( ( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_MACROVAR ||
HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_MACROTEXT ) &&
( fStop ? pToken->pNext : pToken->pNext->pNext ) == pNext )
{
USHORT len = 0;
while( ++len < pToken->len &&
HB_PP_ISNEXTIDCHAR( pToken->value[ len ] ) );
if( len == pToken->len ||
( len == pToken->len - 1 && pToken->value[ len ] == '.' ) )
if( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_MACROVAR )
{
hb_pp_tokenAdd( &pResultPtr, pToken->value + 1, len - 1,
hb_pp_tokenAdd( &pResultPtr, pToken->value + 1, pToken->len -
( pToken->value[ pToken->len - 1 ] == '.' ? 2 : 1 ),
fFirst ? spaces : pToken->spaces,
HB_PP_TOKEN_KEYWORD );
}
@@ -4290,7 +4315,132 @@ static PHB_PP_TOKEN hb_pp_getToken( PHB_PP_STATE pState )
return pState->pTokenOut;
}
static void hb_pp_initDynDefines( PHB_PP_STATE pState )
/*
* exported functions
*/
/*
* internal function to initialize predefined PP rules
*/
void hb_pp_initRules( PHB_PP_RULE * pRulesPtr, int * piRules,
const HB_PP_DEFRULE pDefRules[], int iDefRules )
{
PHB_PP_DEFRULE pDefRule;
PHB_PP_MARKER pMarkers;
PHB_PP_RULE pRule;
hb_pp_ruleListFree( pRulesPtr );
* piRules = iDefRules;
while( --iDefRules >= 0 )
{
pDefRule = ( PHB_PP_DEFRULE ) pDefRules + iDefRules;
if( pDefRule->markers > 0 )
{
USHORT marker;
ULONG ulBit;
pMarkers = ( PHB_PP_MARKER ) hb_xgrab( pDefRule->markers * sizeof( HB_PP_MARKER ) );
memset( pMarkers, '\0', pDefRule->markers * sizeof( HB_PP_MARKER ) );
for( marker = 0, ulBit = 1; marker < pDefRule->markers; ++marker, ulBit <<= 1 )
{
if( pDefRule->repeatbits & ulBit )
pMarkers[ marker ].canrepeat = TRUE;
}
}
else
pMarkers = NULL;
pRule = hb_pp_ruleNew( pDefRule->pMatch, pDefRule->pResult,
pDefRule->mode, pDefRule->markers, pMarkers );
pRule->pPrev = * pRulesPtr;
* pRulesPtr = pRule;
}
}
/*
* create new PP context
*/
PHB_PP_STATE hb_pp_new( void )
{
return hb_pp_stateNew();
}
/*
* free PP context
*/
void hb_pp_free( PHB_PP_STATE pState )
{
hb_pp_stateFree( pState );
}
/*
* initialize PP context
*/
void hb_pp_init( PHB_PP_STATE pState, 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_INLINE_FUNC pInLineFunc,
PHB_PP_SWITCH_FUNC pSwitchFunc )
{
pState->fQuiet = fQuiet;
pState->pOpenFunc = pOpenFunc;
pState->pCloseFunc = pCloseFunc;
pState->pErrorFunc = pErrorFunc;
pState->pDispFunc = pDispFunc;
pState->pDumpFunc = pDumpFunc;
pState->pInLineFunc = pInLineFunc;
pState->pSwitchFunc = pSwitchFunc;
}
/*
* reset PP context, used for multiple .prg file compilation
* with DO ... or *.clp files
*/
void hb_pp_reset( PHB_PP_STATE pState )
{
pState->fError = FALSE;
hb_pp_InFileFree( pState );
hb_pp_OutFileFree( pState );
hb_pp_ruleNonStdFree( &pState->pDefinitions );
hb_pp_ruleNonStdFree( &pState->pTranslations );
hb_pp_ruleNonStdFree( &pState->pCommands );
}
/*
* add search path for included files
*/
void hb_pp_addSearchPath( PHB_PP_STATE pState, const char * szPath, BOOL fReplace )
{
if( fReplace && pState->pIncludePath )
{
hb_fsFreeSearchPath( pState->pIncludePath );
pState->pIncludePath = NULL;
}
if( szPath && * szPath )
{
hb_fsAddSearchPath( szPath, &pState->pIncludePath );
}
}
/*
* mark current rules as standard ones
*/
void hb_pp_setStdBase( PHB_PP_STATE pState )
{
pState->fError = FALSE;
hb_pp_ruleSetStd( pState->pDefinitions );
hb_pp_ruleSetStd( pState->pTranslations );
hb_pp_ruleSetStd( pState->pCommands );
}
/*
* initialize dynamic definitions
*/
void hb_pp_initDynDefines( PHB_PP_STATE pState )
{
char szDefine[ 65 ];
char szResult[ 65 ];
@@ -4369,198 +4519,37 @@ static void hb_pp_initDynDefines( PHB_PP_STATE pState )
#endif
}
/*
* exported functions
* read preprocess rules from file
*/
/*
* internal function to initialize predefined PP rules
*/
void hb_pp_initRules( PHB_PP_RULE * pRulesPtr, int * piRules,
const HB_PP_DEFRULE pDefRules[], int iDefRules )
void hb_pp_readRules( PHB_PP_STATE pState, char * szRulesFile )
{
PHB_PP_DEFRULE pDefRule;
PHB_PP_MARKER pMarkers;
PHB_PP_RULE pRule;
char szFileName[ _POSIX_PATH_MAX + 1 ];
PHB_PP_FILE pFile = pState->pFile;
PHB_FNAME pFileName;
hb_pp_ruleListFree( pRulesPtr );
* piRules = iDefRules;
pFileName = hb_fsFNameSplit( szRulesFile );
if( !pFileName->szExtension )
pFileName->szExtension = ".ch";
hb_fsFNameMerge( szFileName, pFileName );
hb_xfree( pFileName );
while( --iDefRules >= 0 )
pState->pFile = hb_pp_FileNew( pState, szFileName, FALSE, NULL, pState->pOpenFunc );
if( !pState->pFile )
{
pDefRule = ( PHB_PP_DEFRULE ) pDefRules + iDefRules;
if( pDefRule->markers > 0 )
{
USHORT marker;
ULONG ulBit;
pMarkers = ( PHB_PP_MARKER ) hb_xgrab( pDefRule->markers * sizeof( HB_PP_MARKER ) );
memset( pMarkers, '\0', pDefRule->markers * sizeof( HB_PP_MARKER ) );
for( marker = 0, ulBit = 1; marker < pDefRule->markers; ++marker, ulBit <<= 1 )
{
if( pDefRule->repeatbits & ulBit )
pMarkers[ marker ].canrepeat = TRUE;
}
}
else
pMarkers = NULL;
pRule = hb_pp_ruleNew( pDefRule->pMatch, pDefRule->pResult,
pDefRule->mode, pDefRule->markers, pMarkers );
pRule->pPrev = * pRulesPtr;
* pRulesPtr = pRule;
pState->pFile = pFile;
hb_pp_error( pState, 'F', HB_PP_ERR_CANNOT_OPEN_RULES, szFileName );
}
}
/*
* create new PP context
*/
PHB_PP_STATE hb_pp_new( void )
{
return hb_pp_stateNew();
}
/*
* mark current rules as standard ones
*/
void hb_pp_setStdBase( PHB_PP_STATE pState )
{
pState->fError = FALSE;
hb_pp_ruleSetStd( pState->pDefinitions );
hb_pp_ruleSetStd( pState->pTranslations );
hb_pp_ruleSetStd( pState->pCommands );
}
/*
* set stream mode
*/
void hb_pp_setStream( PHB_PP_STATE pState, int iMode )
{
pState->fError = FALSE;
switch( iMode )
else
{
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
*/
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_INLINE_FUNC pInLineFunc,
PHB_PP_SWITCH_FUNC pSwitchFunc )
{
pState->fQuiet = fQuiet;
pState->pOpenFunc = pOpenFunc;
pState->pCloseFunc = pCloseFunc;
pState->pErrorFunc = pErrorFunc;
pState->pDispFunc = pDispFunc;
pState->pDumpFunc = pDumpFunc;
pState->pInLineFunc = pInLineFunc;
pState->pSwitchFunc = pSwitchFunc;
if( !szStdCh )
{
hb_pp_initStaticRules( pState );
}
else if( * szStdCh )
{
char szFileName[ _POSIX_PATH_MAX + 1 ];
PHB_PP_FILE pFile = pState->pFile;
PHB_FNAME pFileName;
pFileName = hb_fsFNameSplit( szStdCh );
if( !pFileName->szExtension )
pFileName->szExtension = ".ch";
hb_fsFNameMerge( szFileName, pFileName );
hb_xfree( pFileName );
pState->pFile = hb_pp_FileNew( pState, szFileName, FALSE, NULL, pState->pOpenFunc );
if( !pState->pFile )
pState->iFiles++;
while( hb_pp_getToken( pState ) );
if( pState->pFile )
{
pState->pFile = pFile;
hb_pp_error( pState, 'F', HB_PP_ERR_CANNOT_OPEN_RULES, szFileName );
}
else
{
pState->iFiles++;
while( hb_pp_getToken( pState ) );
if( pState->pFile )
hb_pp_FileFree( pState->pFile, pState->pCloseFunc );
pState->pFile = pFile;
hb_pp_FileFree( pState->pFile, pState->pCloseFunc );
pState->iFiles--;
}
}
else if( !pState->fQuiet )
{
hb_pp_disp( pState, "Standard command definitions excluded.\n" );
}
hb_pp_initDynDefines( pState );
hb_pp_setStdBase( pState );
}
/*
* free PP context
*/
void hb_pp_free( PHB_PP_STATE pState )
{
hb_pp_stateFree( pState );
}
/*
* reset PP context, used for multiple .prg file compilation
* with DO ... or *.clp files
*/
void hb_pp_reset( PHB_PP_STATE pState )
{
pState->fError = FALSE;
hb_pp_InFileFree( pState );
hb_pp_OutFileFree( pState );
hb_pp_ruleNonStdFree( &pState->pDefinitions );
hb_pp_ruleNonStdFree( &pState->pTranslations );
hb_pp_ruleNonStdFree( &pState->pCommands );
}
/*
* add search path for included files
*/
void hb_pp_addSearchPath( PHB_PP_STATE pState, const char * szPath, BOOL fReplace )
{
if( fReplace && pState->pIncludePath )
{
hb_fsFreeSearchPath( pState->pIncludePath );
pState->pIncludePath = NULL;
}
if( szPath && * szPath )
{
hb_fsAddSearchPath( szPath, &pState->pIncludePath );
pState->pFile = pFile;
}
}
@@ -4638,6 +4627,98 @@ char * hb_pp_outFileName( PHB_PP_STATE pState )
return pState->szOutFileName;
}
/*
* add new define value
*/
void hb_pp_addDefine( PHB_PP_STATE pState, char * szDefName, char * szDefValue )
{
PHB_PP_TOKEN pMatch, pResult, pToken;
PHB_PP_FILE pFile;
pState->fError = FALSE;
pFile = hb_pp_FileBufNew( szDefName, strlen( szDefName ) );
pFile->pPrev = pState->pFile;
pState->pFile = pFile;
pState->iFiles++;
hb_pp_getLine( pState );
pMatch = pState->pFile->pTokenList;
pState->pFile->pTokenList = NULL;
pToken = hb_pp_tokenResultEnd( &pMatch, TRUE );
hb_pp_tokenListFree( &pToken );
if( szDefValue && !pState->fError )
{
pFile->pLineBuf = szDefValue;
pFile->ulLineBufLen = strlen( szDefValue );
hb_pp_getLine( pState );
pResult = pState->pFile->pTokenList;
pState->pFile->pTokenList = NULL;
pToken = hb_pp_tokenResultEnd( &pResult, TRUE );
hb_pp_tokenListFree( &pToken );
}
else
pResult = NULL;
if( pState->fError || !pMatch )
{
hb_pp_tokenListFree( &pMatch );
hb_pp_tokenListFree( &pResult );
}
else
{
hb_pp_defineAdd( pState, HB_PP_CMP_CASE, 0, NULL, pMatch, pResult );
}
pState->pFile = pFile->pPrev;
hb_pp_FileFree( pFile, NULL );
pState->iFiles--;
}
/*
* delete define value
*/
void hb_pp_delDefine( PHB_PP_STATE pState, char * szDefName )
{
PHB_PP_TOKEN pToken;
pToken = hb_pp_tokenNew( szDefName, strlen( szDefName ),
0, HB_PP_TOKEN_KEYWORD );
hb_pp_defineDel( pState, pToken );
hb_pp_tokenFree( pToken );
}
/*
* 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;
}
}
/*
* return next preprocessed line
*/
@@ -4767,61 +4848,63 @@ char * hb_pp_parseLine( PHB_PP_STATE pState, char * pLine, ULONG * pulLen )
}
/*
* add new define value
* create new PP context for macro compiler
*/
void hb_pp_addDefine( PHB_PP_STATE pState, char * szDefName, char * szDefValue )
PHB_PP_STATE hb_pp_lexNew( char * pMacroString, ULONG ulLen )
{
PHB_PP_TOKEN pMatch, pResult, pToken;
PHB_PP_FILE pFile;
PHB_PP_STATE pState = hb_pp_new();
pState->fError = FALSE;
pFile = hb_pp_FileBufNew( szDefName, strlen( szDefName ) );
pFile->pPrev = pState->pFile;
pState->pFile = pFile;
pState->iFiles++;
pState->fQuiet = TRUE;
pState->pFile = hb_pp_FileBufNew( pMacroString, ulLen );
hb_pp_getLine( pState );
pMatch = pState->pFile->pTokenList;
pState->pTokenOut = pState->pFile->pTokenList;
pState->pFile->pTokenList = NULL;
pToken = hb_pp_tokenResultEnd( &pMatch, TRUE );
hb_pp_tokenListFree( &pToken );
if( szDefValue && !pState->fError )
hb_pp_FileFree( pState->pFile, NULL );
pState->pFile = NULL;
if( pState->fError )
{
pFile->pLineBuf = szDefValue;
pFile->ulLineBufLen = strlen( szDefValue );
hb_pp_getLine( pState );
pResult = pState->pFile->pTokenList;
pState->pFile->pTokenList = NULL;
pToken = hb_pp_tokenResultEnd( &pResult, TRUE );
hb_pp_tokenListFree( &pToken );
hb_pp_free( pState );
pState = NULL;
}
else
pResult = NULL;
pState->pNextTokenPtr = &pState->pTokenOut;
if( pState->fError || !pMatch )
{
hb_pp_tokenListFree( &pMatch );
hb_pp_tokenListFree( &pResult );
}
else
{
hb_pp_defineAdd( pState, HB_PP_CMP_CASE, 0, NULL, pMatch, pResult );
}
pState->pFile = pFile->pPrev;
hb_pp_FileFree( pFile, NULL );
pState->iFiles--;
return pState;
}
PHB_PP_TOKEN hb_pp_lex( PHB_PP_STATE pState )
{
PHB_PP_TOKEN pToken = * pState->pNextTokenPtr;
if( pToken )
pState->pNextTokenPtr = &pToken->pNext;
return pToken;
}
/*
* delete define value
* convert token letters to upper cases
* strip leading '&' and trailing '.' (if any) from macrovar token
*/
void hb_pp_delDefine( PHB_PP_STATE pState, char * szDefName )
void hb_pp_tokenUpper( PHB_PP_TOKEN pToken )
{
PHB_PP_TOKEN pToken;
pToken = hb_pp_tokenNew( szDefName, strlen( szDefName ),
0, HB_PP_TOKEN_KEYWORD );
hb_pp_defineDel( pState, pToken );
hb_pp_tokenFree( pToken );
if( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_MACROVAR )
{
char * value;
if( pToken->value[ pToken->len - 1 ] == '.' )
pToken->len--;
value = ( char * ) hb_xgrab( pToken->len );
memcpy( value, pToken->value + 1, pToken->len - 1 );
value[ pToken->len ] = '\0';
if( HB_PP_TOKEN_ALLOC( pToken->type ) )
hb_xfree( pToken->value );
pToken->value = value;
}
else if( !HB_PP_TOKEN_ALLOC( pToken->type ) )
{
char * value = ( char * ) hb_xgrab( pToken->len + 1 );
memcpy( value, pToken->value, pToken->len + 1 );
pToken->value = value;
}
hb_strupr( pToken->value );
}

View File

@@ -62,12 +62,6 @@ void * hb_xrealloc( void * pMem, ULONG ulSize ) { return realloc( pMem, ulSize )
void hb_xfree( void * pMem ) { free( pMem ); }
void hb_pp_initStaticRules( PHB_PP_STATE pState )
{
HB_SYMBOL_UNUSED( pState );
}
/*
* functions to create .c files with rules defined in given PP context
*/
@@ -223,7 +217,7 @@ static void hb_pp_generateRules( FILE * fout, PHB_PP_STATE pState )
if( pState->pCommands )
iCmds = hb_pp_writeRules( fout, pState->pCommands, "cmd" );
fprintf( fout, "\nvoid hb_pp_initStaticRules( PHB_PP_STATE pState )\n{\n" );
fprintf( fout, "\nvoid hb_pp_setStdRules( PHB_PP_STATE pState )\n{\n" );
hb_pp_generateInitFunc( fout, iDefs, "Definitions", "def" );
hb_pp_generateInitFunc( fout, iTrans, "Translations", "trs" );
hb_pp_generateInitFunc( fout, iCmds, "Commands", "cmd" );
@@ -368,7 +362,7 @@ int main( int argc, char * argv[] )
if( szFile )
{
hb_pp_init( pState, NULL, fQuiet, NULL, NULL, NULL, NULL, NULL, NULL, NULL );
hb_pp_init( pState, fQuiet, NULL, NULL, NULL, NULL, NULL, NULL, NULL );
hb_pp_inFile( pState, szFile, NULL );
if( fWrite )
{

View File

@@ -84,15 +84,21 @@ static void hb_pp_Disp( const char * szMessage )
HB_SYMBOL_UNUSED( szMessage );
}
static PHB_PP_STATE hb_pp_stateNew( char * szStdCh )
static PHB_PP_STATE hb_pp_stateNew( BOOL fInit )
{
PHB_PP_STATE pState = hb_pp_new();
if( pState )
{
hb_pp_init( pState, szStdCh, TRUE, NULL, NULL,
hb_pp_init( pState, TRUE, NULL, NULL,
hb_pp_ErrorMessage, hb_pp_Disp, NULL, NULL, NULL );
if( fInit )
{
hb_pp_setStdRules( pState );
hb_pp_initDynDefines( pState );
hb_pp_setStdBase( pState );
}
if( ! s_pp_state )
s_pp_state = pState;
}
@@ -124,7 +130,7 @@ static PHB_PP_STATE hb_pp_stateParam( int * piParam )
{
* piParam = 1;
if( !s_pp_state )
return hb_pp_stateNew( NULL );
return hb_pp_stateNew( TRUE );
else
return s_pp_state;
}
@@ -141,11 +147,21 @@ HB_FUNC( __PP_INIT )
PHB_PP_STATE pState;
hb_pp_stateFree( s_pp_state );
pState = hb_pp_stateNew( hb_parc( 2 ) );
pState = hb_pp_stateNew( FALSE );
if( pState )
{
if( ISCHAR( 1 ) )
hb_pp_addSearchPath( pState, hb_parc( 1 ), TRUE );
char * szPath = hb_parc( 1 ), * szStdCh = hb_parc( 2 );
if( szPath )
hb_pp_addSearchPath( pState, szPath, TRUE );
if( szStdCh )
hb_pp_readRules( pState, szStdCh );
else
hb_pp_setStdRules( pState );
hb_pp_initDynDefines( pState );
hb_pp_setStdBase( pState );
hb_retptr( pState );
}
else

View File

@@ -33,6 +33,7 @@ LIBS=\
rtl \
vm \
macro \
pp \
common \
include $(TOP)$(ROOT)config/bin.cf