/* * Harbour preprocessor * * Copyright 2006 Przemyslaw Czerpak * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file LICENSE.txt. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA (or visit https://www.gnu.org/licenses/). * * As a special exception, the Harbour Project gives permission for * additional uses of the text contained in its release of Harbour. * * The exception is that, if you link the Harbour libraries with other * files to produce an executable, this does not by itself cause the * resulting executable to be covered by the GNU General Public License. * Your use of that executable is in no way restricted on account of * linking the Harbour library code into it. * * This exception does not however invalidate any other reasons why * the executable file might be covered by the GNU General Public License. * * This exception applies only to the code released by the Harbour * Project under the name Harbour. If you copy code from other * Harbour Project or Free Software Foundation releases into a copy of * Harbour, as the General Public License permits, the exception does * not apply to the code that you add in this way. To avoid misleading * anyone as to the status of such modified files, you must delete * this exception notice from them. * * If you write modifications of your own for Harbour, it is your choice * whether to permit this exception to apply to your modifications. * If you do not wish that, delete this exception notice. * */ #ifndef HB_PP_H_ #define HB_PP_H_ #include "hbapi.h" #include "hbapifs.h" HB_EXTERN_BEGIN #define HB_BLOCK_MACROVAR 1 /* #define HB_BLOCK_LATEEVAL 2 */ #define HB_BLOCK_VPARAMS 4 #define HB_BLOCK_EXT 8 #define HB_BLOCK_REDUCE 16 /* #pragma {__text,__stream,__cstream}|functionOut|functionEnd|functionStart */ #define HB_PP_STREAM_OFF 0 /* standard preprocessing */ #define HB_PP_STREAM_COMMENT 1 /* multiline comment */ #define HB_PP_STREAM_DUMP_C 2 /* pragma BEGINDUMP */ #define HB_PP_STREAM_CLIPPER 3 /* Cl*pper 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 sequences processed */ #define HB_PP_STREAM_INLINE_C 6 /* hb_inLIne() {...} data, should not be preprocessed */ #define HB_PP_STREAM_BINARY 7 /* __binarystreaminclude */ /* 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 /* actions returned by function to open included files */ #define HB_PP_OPEN_OK 0 #define HB_PP_OPEN_FILE 1 #define HB_PP_OPEN_ERROR 2 /* function to open included files */ #define HB_PP_OPEN_FUNC_( func ) int func( void *, char *, HB_BOOL, HB_BOOL, HB_BOOL, HB_PATHNAMES *, HB_BOOL *, FILE **, const char **, HB_SIZE *, HB_BOOL * ) typedef HB_PP_OPEN_FUNC_( ( * PHB_PP_OPEN_FUNC ) ); /* function to close included files */ #define HB_PP_CLOSE_FUNC_( func ) void func( void *, FILE * ) typedef HB_PP_CLOSE_FUNC_( ( * PHB_PP_CLOSE_FUNC ) ); /* function to generate errors */ #define HB_PP_ERROR_FUNC_( func ) void func( void *, const char * const *, char, int, const char *, const char * ) typedef HB_PP_ERROR_FUNC_( ( * PHB_PP_ERROR_FUNC ) ); /* function to redirect stdout messages */ #define HB_PP_DISP_FUNC_( func ) void func( void *, const char * ) typedef HB_PP_DISP_FUNC_( ( * PHB_PP_DISP_FUNC ) ); /* function for catching #pragma dump data */ #define HB_PP_DUMP_FUNC_( func ) void func( void *, char *, HB_SIZE, int ) typedef HB_PP_DUMP_FUNC_( ( * PHB_PP_DUMP_FUNC ) ); /* function for catching HB_INLINE(...){...} data */ #define HB_PP_INLINE_FUNC_( func ) void func( void *, char *, char *, HB_SIZE, int ) typedef HB_PP_INLINE_FUNC_( ( * PHB_PP_INLINE_FUNC ) ); /* function for catching #pragma dump data */ #define HB_PP_SWITCH_FUNC_( func ) HB_BOOL func( void *, const char *, int *, HB_BOOL ) typedef HB_PP_SWITCH_FUNC_( ( * PHB_PP_SWITCH_FUNC ) ); /* function to register included files */ #define HB_PP_INC_FUNC_( func ) void func( void *, const char * ) typedef HB_PP_INC_FUNC_( ( * PHB_PP_INC_FUNC ) ); /* function to generate errors */ #define HB_PP_MSG_FUNC_( func ) void func( void * cargo, int iErrorFmt, int iLine, const char * szModule, char cPrefix, int iValue, const char * szText, const char * szPar1, const char * szPar2 ) typedef HB_PP_MSG_FUNC_( ( * PHB_PP_MSG_FUNC ) ); /* preprocessor tokens */ #define HB_PP_TOKEN_NUL 0 #define HB_PP_MMARKER_REGULAR 1 #define HB_PP_MMARKER_LIST 2 #define HB_PP_MMARKER_RESTRICT 3 #define HB_PP_MMARKER_WILD 4 #define HB_PP_MMARKER_EXTEXP 5 #define HB_PP_MMARKER_NAME 6 #define HB_PP_MMARKER_OPTIONAL 7 #define HB_PP_RMARKER_REGULAR 11 #define HB_PP_RMARKER_STRDUMP 12 #define HB_PP_RMARKER_STRSTD 13 #define HB_PP_RMARKER_STRSMART 14 #define HB_PP_RMARKER_BLOCK 15 #define HB_PP_RMARKER_LOGICAL 16 #define HB_PP_RMARKER_NUL 17 #define HB_PP_RMARKER_OPTIONAL 18 #define HB_PP_RMARKER_DYNVAL 19 #define HB_PP_RMARKER_REFERENCE 20 /* keywords, pseudo keywords and PP only tokens */ #define HB_PP_TOKEN_KEYWORD 21 #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 #define HB_PP_TOKEN_NUMBER 42 #define HB_PP_TOKEN_DATE 43 #define HB_PP_TOKEN_TIMESTAMP 44 #define HB_PP_TOKEN_LOGICAL 45 /* operators */ #define HB_PP_TOKEN_LEFT_PB 50 #define HB_PP_TOKEN_RIGHT_PB 51 #define HB_PP_TOKEN_LEFT_SB 52 #define HB_PP_TOKEN_RIGHT_SB 53 #define HB_PP_TOKEN_LEFT_CB 54 #define HB_PP_TOKEN_RIGHT_CB 55 #define HB_PP_TOKEN_REFERENCE 56 #define HB_PP_TOKEN_AMPERSAND 57 #define HB_PP_TOKEN_SEND 58 #define HB_PP_TOKEN_ALIAS 59 #define HB_PP_TOKEN_ASSIGN 60 #define HB_PP_TOKEN_PLUSEQ 61 #define HB_PP_TOKEN_MINUSEQ 62 #define HB_PP_TOKEN_MULTEQ 63 #define HB_PP_TOKEN_DIVEQ 64 #define HB_PP_TOKEN_MODEQ 65 #define HB_PP_TOKEN_EXPEQ 66 #define HB_PP_TOKEN_INC 67 #define HB_PP_TOKEN_DEC 68 #define HB_PP_TOKEN_NOT 69 #define HB_PP_TOKEN_OR 70 #define HB_PP_TOKEN_AND 71 #define HB_PP_TOKEN_EQUAL 72 #define HB_PP_TOKEN_EQ 73 #define HB_PP_TOKEN_LT 74 #define HB_PP_TOKEN_GT 75 #define HB_PP_TOKEN_LE 76 #define HB_PP_TOKEN_GE 77 #define HB_PP_TOKEN_NE 78 #define HB_PP_TOKEN_IN 79 #define HB_PP_TOKEN_PLUS 80 #define HB_PP_TOKEN_MINUS 81 #define HB_PP_TOKEN_MULT 82 #define HB_PP_TOKEN_DIV 83 #define HB_PP_TOKEN_MOD 84 #define HB_PP_TOKEN_POWER 85 #define HB_PP_TOKEN_EPSILON 86 #define HB_PP_TOKEN_SHIFTL 87 #define HB_PP_TOKEN_SHIFTR 88 #define HB_PP_TOKEN_BITXOR 89 #define HB_PP_TOKEN_TYPE(t) ( (t) & 0xff ) /* bitfields */ /* #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_ALLOC(t) ( ( (t) & HB_PP_TOKEN_STATIC ) == 0 ) #define HB_PP_TOKEN_ISPREDEF(t) ( ( (t)->type & HB_PP_TOKEN_PREDEFINED ) != 0 ) /* These macros are very important for the PP behavior. They define what and how will be translated. Their default definitions are not strictly Clipper compatible to allow programmer using indirect # directive EOL - end of line => '\n' or NULL EOC - end of command => EOL or ';' EOS - end of subst => EOL or ';' + '#' EOP - end of pattern => EOL for direct and EOC for indirect */ /* End Of Line */ #define HB_PP_TOKEN_ISEOL(t) ( (t) == NULL || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_EOL ) /* End Of Command */ #define HB_PP_TOKEN_ISEOC(t) ( HB_PP_TOKEN_ISEOL(t) || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_EOC ) #ifdef HB_CLP_STRICT # define HB_PP_TOKEN_ISEOS(t) HB_PP_TOKEN_ISEOL(t) # define HB_PP_TOKEN_ISEOP(t,l) HB_PP_TOKEN_ISEOL(t) #else /* End Of Subst - define how many tokens in line should be translated, Clipper translates whole line */ # define HB_PP_TOKEN_ISEOS(t) ( HB_PP_TOKEN_ISEOL(t) || \ ( HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_EOC && \ (t)->pNext && \ ( HB_PP_TOKEN_TYPE((t)->pNext->type) == HB_PP_TOKEN_HASH || \ HB_PP_TOKEN_TYPE((t)->pNext->type) == HB_PP_TOKEN_DIRECTIVE ) ) ) /* End Of Pattern - the second parameter define if it's direct or indirect pattern */ # define HB_PP_TOKEN_ISEOP(t,l) ( (l) ? HB_PP_TOKEN_ISEOL(t) : HB_PP_TOKEN_ISEOC(t) ) #endif #define HB_PP_TOKEN_ISDIRECTIVE(t) ( HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_DIRECTIVE || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_HASH ) #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_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 && \ HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_DATE && \ HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_TIMESTAMP && \ HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_LOGICAL ) #define HB_PP_TOKEN_OPEN_BR(t) ( HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_LEFT_PB || \ HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_LEFT_SB || \ HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_LEFT_CB ) #define HB_PP_TOKEN_CLOSE_BR(t) ( 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 ) #define HB_PP_TOKEN_ISNEUTRAL(t) ( HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_DEC || \ HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_INC ) #define HB_PP_TOKEN_NEEDLEFT(t) ( HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_ASSIGN || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_PLUSEQ || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_MINUSEQ || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_MULTEQ || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_DIVEQ || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_MODEQ || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_EXPEQ || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_EQUAL || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_EQ || \ ( HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_SEND && \ (t)->spaces == 0 && (t)->pNext && \ ( HB_PP_TOKEN_TYPE((t)->pNext->type) == HB_PP_TOKEN_KEYWORD || \ HB_PP_TOKEN_TYPE((t)->pNext->type) == HB_PP_TOKEN_MACROVAR || \ HB_PP_TOKEN_TYPE((t)->pNext->type) == HB_PP_TOKEN_MACROTEXT ) ) ) /* I do not want to replicate exactly Clipper PP behavior and check if expression is valid. it's wrong and causes that potentially valid expressions are not properly parsed, f.e: ? 1 + + 2 does not work when QOut( 1 + + 2 ) perfectly does. It this difference will be reason of some problems then please inform me with a code example so I'll be able if it should be implemented or not. Now I simply disabled HB_PP_TOKEN_NEEDRIGHT() macro. */ #ifndef HB_CLP_STRICT #define HB_PP_TOKEN_NEEDRIGHT(t) ( HB_FALSE ) #else #define HB_PP_TOKEN_NEEDRIGHT(t) ( HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_PLUS || \ HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_MINUS || \ HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_MULT || \ HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_DIV || \ HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_MOD || \ HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_POWER ) #endif #ifdef HB_CLP_STRICT # define HB_PP_TOKEN_ISUNARY(t) ( HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_MINUS || \ HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_DEC || \ HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_INC || \ HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_AMPERSAND ) #else # define HB_PP_TOKEN_ISUNARY(t) ( HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_MINUS || \ HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_DEC || \ HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_INC || \ HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_AMPERSAND || \ HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_PLUS || \ HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_NOT || \ HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_REFERENCE ) #endif #define HB_PP_TOKEN_ISMATCH(t) ( (t) && ( (t)->type & HB_PP_TOKEN_MATCHMARKER ) != 0 ) #if 0 #define HB_PP_TOKEN_ISRESULT(t) ( HB_PP_TOKEN_TYPE(t) == HB_PP_RMARKER_REGULAR || \ HB_PP_TOKEN_TYPE(t) == HB_PP_RMARKER_STRDUMP || \ HB_PP_TOKEN_TYPE(t) == HB_PP_RMARKER_STRSTD || \ HB_PP_TOKEN_TYPE(t) == HB_PP_RMARKER_STRSMART || \ HB_PP_TOKEN_TYPE(t) == HB_PP_RMARKER_BLOCK || \ HB_PP_TOKEN_TYPE(t) == HB_PP_RMARKER_LOGICAL || \ HB_PP_TOKEN_TYPE(t) == HB_PP_RMARKER_NUL ) #endif #define HB_PP_TOKEN_ISEXPVAL(t) ( HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_KEYWORD || \ 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 || \ HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_TIMESTAMP ) #define HB_PP_TOKEN_ISEXPTOKEN(t) ( HB_PP_TOKEN_ISEXPVAL( (t)->type ) || \ ( (t)->pNext && HB_PP_TOKEN_ISUNARY( (t)->type ) && \ HB_PP_TOKEN_ISEXPVAL( (t)->pNext->type ) ) ) #ifdef HB_CLP_STRICT /* Clipper supports quoting by [] for 1st token in the line so we are not checking for HB_PP_TOKEN_NUL in this macro */ #define HB_PP_TOKEN_CANQUOTE(t) ( HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_KEYWORD && \ 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 ) #else /* Disable string quoting by [] for next token if current one is constant value - it's not Clipper compatible but we need it for accessing string characters by array index operator or introduce similar extensions for other types in the future */ #define HB_PP_TOKEN_CANQUOTE(t) ( HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_KEYWORD && \ 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 && \ 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 && \ HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_TIMESTAMP && \ HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_LOGICAL ) #endif typedef struct _HB_PP_TOKEN { struct _HB_PP_TOKEN * pNext; /* next token pointer */ struct _HB_PP_TOKEN * pMTokens; /* restrict or optional marker token(s) */ const char * value; /* token value */ HB_SIZE len; /* token value length */ HB_SIZE spaces; /* leading spaces for stringify */ HB_USHORT type; /* token type, see HB_PP_TOKEN_* */ HB_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_REPEATS 128 /* Clipper allows only 16 nested includes */ #define HB_PP_MAX_INCLUDED_FILES 64 #define HB_PP_HASHID(t) ( ( HB_UCHAR ) HB_PP_UPPER( (t)->value[ 0 ] ) ) #define HB_PP_HASHID_MAX 256 #define HB_PP_DEFINE 1 #define HB_PP_TRANSLATE 2 #define HB_PP_COMMAND 4 /* comparison 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_LOG 1 #define HB_PP_PREC_NOT 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 /* For platforms which does not use ASCII based character tables this macros have to be changed to use valid C functions, f.e.: isalpha(), isdigit(), ... */ #ifdef HB_CLP_STRICT # define HB_PP_ISILLEGAL(c) ( (c) < 32 || (c) >= 126 ) #else # define HB_PP_ISILLEGAL(c) ( (c) < 32 || (c) == 127 ) #endif #define HB_PP_ISTEXTCHAR(c) ( (unsigned char) (c) >= 128 ) #define HB_PP_ISBLANK(c) ( (c) == ' ' || (c) == '\t' ) #define HB_PP_ISDIGIT(c) HB_ISDIGIT( c ) #define HB_PP_ISHEX(c) HB_ISXDIGIT( c ) #define HB_PP_ISTRUE(c) ( (c) == 'T' || (c) == 't' || \ (c) == 'Y' || (c) == 'y' ) #define HB_PP_ISFALSE(c) ( (c) == 'F' || (c) == 'f' || \ (c) == 'N' || (c) == 'n' ) #define HB_PP_ISFIRSTIDCHAR(c) HB_ISFIRSTIDCHAR( c ) #define HB_PP_ISNEXTIDCHAR(c) HB_ISNEXTIDCHAR( c ) #define HB_PP_UPPER(c) HB_TOUPPER( c ) typedef struct _HB_PP_RESULT { struct _HB_PP_RESULT * pNext; PHB_PP_TOKEN pFirstToken; PHB_PP_TOKEN pNextExpr; } HB_PP_RESULT, * PHB_PP_RESULT; typedef struct _HB_PP_MARKERPTR { struct _HB_PP_MARKERPTR * pNext; PHB_PP_TOKEN pToken; PHB_PP_TOKEN pMTokens; HB_USHORT type; } HB_PP_MARKERPTR, * PHB_PP_MARKERPTR; typedef struct _HB_PP_MARKERLST { struct _HB_PP_MARKERLST * pNext; PHB_PP_MARKERPTR pMatchMarkers; HB_USHORT canrepeat; HB_USHORT index; } HB_PP_MARKERLST, * PHB_PP_MARKERLST; typedef struct { HB_USHORT canrepeat; /* filled when pattern matches for substitution, cleared after */ HB_USHORT matches; PHB_PP_RESULT pResult; } HB_PP_MARKER, * PHB_PP_MARKER; typedef struct _HB_PP_RULE { struct _HB_PP_RULE * pPrev; /* previous rule */ PHB_PP_TOKEN pMatch; /* match pattern or NULL */ PHB_PP_TOKEN pResult; /* result pattern or NULL */ HB_USHORT mode; /* comparison mode HB_PP_CMP_* */ HB_USHORT markers; /* number of markers in marker table */ /* filled when pattern matches for substitution, cleared after */ PHB_PP_MARKER pMarkers; /* marker table */ PHB_PP_TOKEN pNextExpr; /* next expression after match pattern */ } HB_PP_RULE, * PHB_PP_RULE; typedef struct _HB_PP_DEFRULE { PHB_PP_TOKEN pMatch; PHB_PP_TOKEN pResult; HB_USHORT mode; HB_USHORT markers; HB_ULONG repeatbits; } HB_PP_DEFRULE, * PHB_PP_DEFRULE; typedef struct { const char * name; /* input name */ HB_SIZE len; /* input name length */ const char * value; /* output name */ HB_USHORT type; /* HB_PP_TOKEN_* */ } HB_PP_OPERATOR, * PHB_PP_OPERATOR; typedef struct { char * pBufPtr; HB_SIZE nLen; HB_SIZE nAllocated; } HB_MEM_BUFFER, * PHB_MEM_BUFFER; typedef struct _HB_PP_FILE { char * szFileName; /* input file name */ FILE * file_in; /* input file handle */ PHB_PP_TOKEN pTokenList; /* current line decoded to tokens */ int iCurrentLine; /* current line in file */ int iLastLine; /* last non empty generated line */ int iLastDisp; /* last shown line number */ int iTokens; /* number of decoded tokens */ HB_BOOL fGenLineInfo; /* #line information should be generated */ HB_BOOL fEof; /* the end of file reached */ HB_BOOL fFree; /* free external buffer */ const char * pLineBuf; /* buffer for parsing external lines */ HB_SIZE nLineBufLen; /* size of external line buffer */ struct _HB_PP_FILE * pPrev; /* previous file, the one which included this file */ } HB_PP_FILE, * PHB_PP_FILE; typedef struct { /* common for all included files */ PHB_PP_OPERATOR pOperators; /* user defined operators */ PHB_PP_RULE pDefinitions; /* #define table */ PHB_PP_RULE pTranslations; /* #[x]translate table */ PHB_PP_RULE pCommands; /* #[x]command table */ int iOperators; /* number of user defined operators */ int iDefinitions; /* number of rules in pDefinitions */ int iTranslations; /* number of rules in pTranslations */ int iCommands; /* number of rules in pCommands */ HB_BYTE pMap[ HB_PP_HASHID_MAX ]; /* translation map */ PHB_PP_TOKEN pTokenOut; /* preprocessed tokens */ PHB_PP_TOKEN * pNextTokenPtr; /* pointer to the last NULL pointer in token list */ PHB_MEM_BUFFER pDumpBuffer; /* buffer for dump output */ PHB_MEM_BUFFER pOutputBuffer; /* buffer for preprocessed line */ int iLineTot; /* total number of parsed lines */ int iCycle; /* translation counter */ int iMaxCycles; /* maximum number of translations (current) */ int iMaxCyclesSet; /* maximum number of translations (default) */ HB_BOOL fTracePragmas; /* display information about set pragmas */ HB_BOOL fWritePreprocesed; /* write preprocessed data to file (.ppo) */ HB_BOOL fWriteTrace; /* write translation to file (.ppt) */ HB_PATHNAMES * pIncludePath; /* search path(s) for included files */ char * szOutFileName; /* output file name */ FILE * file_out; /* output file handle */ char * szTraceFileName; /* trace output file name */ FILE * file_trace; /* trace output file handle */ HB_BOOL fQuietSet; /* do not show standard information (default) */ HB_BOOL fQuiet; /* do not show standard information (current) */ HB_BOOL fGauge; /* do not show line counter gauge */ HB_BOOL fEscStr; /* use \ in strings as escape character */ HB_BOOL fMultiLineStr; /* allow to define multiline [] and e"" strings using ; as line concatenator */ HB_BOOL fError; /* indicates error in last operation */ int iErrors; /* number of error during preprocessing */ int iCondCompile; /* current conditional compilation flag, when not 0 disable preprocessing and output */ int iCondCount; /* number of nested #if[n]def directive */ int iCondStackSize; /* size of conditional compilation stack */ int * pCondStack; /* conditional compilation stack */ /* used to divide line per tokens and tokens manipulations */ PHB_MEM_BUFFER pBuffer; /* buffer for input and output line */ HB_SIZE nSpaces; /* leading spaces for next token */ HB_SIZE nSpacesNL; /* leading spaces ';' token (fCanNextLine) if it will not be line concatenator */ HB_SIZE nSpacesMin; /* minimal number of leading spaces for next token */ HB_USHORT usLastType; /* last token type */ HB_BOOL fCanNextLine; /* ';' token found and we do not know yet if it's command separator or line concatenator */ HB_BOOL fDirective; /* # directives is parsed */ HB_BOOL fNewStatement; /* set to HB_TRUE at line beginning or after each ';' token */ PHB_PP_TOKEN pFuncOut; /* function used for each line in HB_PP_STREAM_* dumping */ PHB_PP_TOKEN pFuncEnd; /* end function for HB_PP_STREAM_* dumping */ 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() */ int iNestedBlock; /* nested extended block counter */ int iBlockState; /* state of extended block declaration */ PHB_PP_FILE pFile; /* currently preprocessed file structure */ int iFiles; /* number of open files */ void * cargo; /* parameter passed to user functions */ PHB_PP_OPEN_FUNC pOpenFunc; /* function to open files */ PHB_PP_CLOSE_FUNC pCloseFunc; /* function to close files */ PHB_PP_ERROR_FUNC pErrorFunc; /* function to generate errors */ PHB_PP_DISP_FUNC pDispFunc; /* function to redirect stdout messages */ PHB_PP_DUMP_FUNC pDumpFunc; /* function for catching #pragma dump data */ PHB_PP_INC_FUNC pIncFunc; /* function to register included files */ PHB_PP_INLINE_FUNC pInLineFunc; /* function for hb_inLine(...) {...} blocks */ PHB_PP_SWITCH_FUNC pSwitchFunc; /* function for compiler switches with #pragma ... */ } HB_PP_STATE, * PHB_PP_STATE; extern void hb_pp_initRules( PHB_PP_RULE * pRulesPtr, int * piRules, const HB_PP_DEFRULE pDefRules[], int iDefRules ); #else typedef void * PHB_PP_STATE; #endif /* _HB_PP_INTERNAL */ /* public functions */ extern HB_EXPORT PHB_PP_STATE hb_pp_new( void ); extern HB_EXPORT void hb_pp_free( PHB_PP_STATE pState ); extern HB_EXPORT void hb_pp_reset( PHB_PP_STATE pState ); extern HB_EXPORT void hb_pp_init( PHB_PP_STATE pState, HB_BOOL fQuiet, HB_BOOL fGauge, int iCycles, void * cargo, 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 HB_EXPORT void hb_pp_initDynDefines( PHB_PP_STATE pState, HB_BOOL fArchDefs ); extern HB_EXPORT void hb_pp_setIncFunc( PHB_PP_STATE pState, PHB_PP_INC_FUNC pIncFunc ); extern HB_EXPORT void hb_pp_readRules( PHB_PP_STATE pState, const char * szRulesFile ); extern HB_EXPORT void hb_pp_setStdRules( PHB_PP_STATE pState ); extern HB_EXPORT void hb_pp_setStdBase( PHB_PP_STATE pState ); extern HB_EXPORT void hb_pp_setStream( PHB_PP_STATE pState, int iMode ); extern HB_EXPORT void hb_pp_addSearchPath( PHB_PP_STATE pState, const char * szPath, HB_BOOL fReplace ); extern HB_EXPORT HB_BOOL hb_pp_inBuffer( PHB_PP_STATE pState, const char * szFileName, const char * pBuffer, HB_SIZE nLen, int iStartLine ); extern HB_EXPORT HB_BOOL hb_pp_inFile( PHB_PP_STATE pState, const char * szFileName, HB_BOOL fSearchPath, FILE * file_in, HB_BOOL fError ); extern HB_EXPORT HB_BOOL hb_pp_outFile( PHB_PP_STATE pState, const char * szOutFileName, FILE * file_out ); extern HB_EXPORT HB_BOOL hb_pp_traceFile( PHB_PP_STATE pState, const char * szTraceFileName, FILE * file_trace ); extern HB_EXPORT char * hb_pp_fileName( PHB_PP_STATE pState ); extern HB_EXPORT int hb_pp_line( PHB_PP_STATE pState ); extern HB_EXPORT HB_BOOL hb_pp_eof( PHB_PP_STATE pState ); extern HB_EXPORT int hb_pp_lineTot( PHB_PP_STATE pState ); extern HB_EXPORT char * hb_pp_outFileName( PHB_PP_STATE pState ); extern HB_EXPORT char * hb_pp_traceFileName( PHB_PP_STATE pState ); extern HB_EXPORT char * hb_pp_nextLine( PHB_PP_STATE pState, HB_SIZE * pnLen ); extern HB_EXPORT char * hb_pp_parseLine( PHB_PP_STATE pState, const char * pLine, HB_SIZE * pnLen ); extern HB_EXPORT void hb_pp_addDefine( PHB_PP_STATE pState, const char * szDefName, const char * szDefValue ); extern HB_EXPORT void hb_pp_delDefine( PHB_PP_STATE pState, const char * szDefName ); extern HB_EXPORT HB_BOOL hb_pp_lasterror( PHB_PP_STATE pState ); extern HB_EXPORT int hb_pp_errorCount( PHB_PP_STATE pState ); extern HB_EXPORT void hb_pp_tokenUpper( PHB_PP_TOKEN pToken ); extern HB_EXPORT void hb_pp_tokenToString( PHB_PP_STATE pState, PHB_PP_TOKEN pToken ); extern HB_EXPORT char * hb_pp_tokenBlockString( PHB_PP_STATE pState, PHB_PP_TOKEN pToken, int * piType, HB_SIZE * pnLen ); extern HB_EXPORT PHB_PP_STATE hb_pp_lexNew( const char * pString, HB_SIZE nLen ); extern HB_EXPORT PHB_PP_TOKEN hb_pp_lexGet( PHB_PP_STATE pState ); extern HB_EXPORT PHB_PP_TOKEN hb_pp_tokenGet( PHB_PP_STATE pState ); extern HB_EXPORT HB_BOOL hb_pp_tokenNextExp( PHB_PP_TOKEN * pTokenPtr ); /* PP lib helper functions */ extern PHB_PP_STATE hb_pp_Param( int iParam ); HB_EXTERN_END #endif /* HB_PP_H_ */