diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 8e83fce550..18de14829b 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,37 @@ 2002-12-01 13:30 UTC+0100 Foo Bar */ +2006-11-25 19:30 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/include/hbexpra.c + * harbour/include/hbexprb.c + * harbour/include/hbexprc.c + * harbour/include/hbexprop.h + * harbour/source/common/expropt1.c + * harbour/source/common/expropt2.c + * harbour/source/compiler/complex.c + * harbour/source/compiler/harbour.c + * harbour/source/compiler/harbour.y + * harbour/source/macro/macro.y + + added support for strings with with ASCII NUL character + Strings with ASCII NUL character are not stored with hash table + but dynamically allocated/deallocated + ! fixed compilation of strings with ASCII NUL character which + can appear in escaped strings e"..." or after compiler chr(0) + optimization + % removed some not longer necessary memory allocations + + * harbour/source/vm/macro.c + ! fixed GPF caused by HB_MACRO structure double freeing + - removed some code which was added as workaround for the old + behavior of HVM QUIT and false FM stat memory leak reports. + It's not longer necessary in current HVM. + + * harbour/source/common/hbstr.c + ! fixed final string size calculation in extended strings + + * harbour/source/compiler/gencli.c + * cleaned Bh may no flush data in PreExt() + * harbour/source/rtl/gtwin/gtwin.c ! fixed Init() code by adding missing SUPER_INIT() * modified a little bit PreExt() and PostExt() methods diff --git a/harbour/include/hbexpra.c b/harbour/include/hbexpra.c index 80ab6f9ba6..ba39a74253 100644 --- a/harbour/include/hbexpra.c +++ b/harbour/include/hbexpra.c @@ -528,7 +528,7 @@ HB_EXPR_PTR hb_compExprNewFunCall( HB_EXPR_PTR pName, HB_EXPR_PTR pParms, HB_COM { /* no second argument */ char *szText = pFirst->value.asMacro.szMacro; - pArg->pNext = hb_compExprNewString( szText, strlen(szText), HB_COMP_PARAM ); + pArg->pNext = hb_compExprNewString( szText, strlen( szText ), FALSE, HB_COMP_PARAM ); pArg->pNext->pNext = pNext; } HB_EXPR_PCODE1( hb_compExprDelete, pFirst ); /* delete first argument */ @@ -656,7 +656,7 @@ HB_EXPR_PTR hb_compExprNewSend( HB_EXPR_PTR pObject, char * szMessage, * In harbour compiler strings are shared in the hash table then they * cannot be deallocated by default */ -HB_EXPR_PTR hb_compExprNewString( char *szValue, ULONG ulLen, HB_COMP_DECL ) +HB_EXPR_PTR hb_compExprNewString( char *szValue, ULONG ulLen, BOOL fDealloc, HB_COMP_DECL ) { HB_EXPR_PTR pExpr; @@ -665,7 +665,7 @@ HB_EXPR_PTR hb_compExprNewString( char *szValue, ULONG ulLen, HB_COMP_DECL ) pExpr =hb_compExprNew( HB_ET_STRING, HB_COMP_PARAM ); pExpr->value.asString.string = szValue; - pExpr->value.asString.dealloc = FALSE; + pExpr->value.asString.dealloc = fDealloc; pExpr->ulLength = ulLen; pExpr->ValType = HB_EV_STRING; diff --git a/harbour/include/hbexprb.c b/harbour/include/hbexprb.c index 5a2a2c6774..04513fd901 100644 --- a/harbour/include/hbexprb.c +++ b/harbour/include/hbexprb.c @@ -350,15 +350,15 @@ static HB_EXPR_FUNC( hb_compExprUseString ) break; case HB_EA_PUSH_PCODE: { - char * szDupl = hb_strupr( hb_strdup( pSelf->value.asString.string ) ); - - HB_EXPR_PCODE2( hb_compGenPushString, pSelf->value.asString.string, pSelf->ulLength + 1 ); + HB_EXPR_PCODE2( hb_compGenPushString, pSelf->value.asString.string, + pSelf->ulLength + 1 ); #if ! defined( HB_MACRO_SUPPORT ) if( HB_COMP_PARAM->fTextSubst ) #endif { BOOL bUseTextSubst; - BOOL bValidMacro = hb_compExprIsValidMacro( szDupl, &bUseTextSubst, HB_COMP_PARAM ); + BOOL bValidMacro = hb_compExprIsValidMacro( pSelf->value.asString.string, + pSelf->ulLength, &bUseTextSubst, HB_COMP_PARAM ); if( bUseTextSubst ) { if( HB_SUPPORT_HARBOUR ) @@ -383,7 +383,6 @@ static HB_EXPR_FUNC( hb_compExprUseString ) } } } - hb_xfree( szDupl ); break; } case HB_EA_POP_PCODE: @@ -567,9 +566,9 @@ static void hb_compExprCodeblockEarly( HB_EXPR_PTR pSelf, HB_COMP_DECL ) HB_EXPR_PTR pVar, pNew; pVar = hb_compExprNewVar( pExpr->value.asMacro.szMacro, HB_COMP_PARAM ); - pNew = hb_compExprNewString( "{||", 3, HB_COMP_PARAM ); + pNew = hb_compExprNewString( "{||", 3, FALSE, HB_COMP_PARAM ); pNew = hb_compExprSetOperand( hb_compExprNewPlus( pNew, HB_COMP_PARAM ), pVar, HB_COMP_PARAM ); - pNew = hb_compExprSetOperand( hb_compExprNewPlus( pNew, HB_COMP_PARAM ), hb_compExprNewString( "}", 1, HB_COMP_PARAM ), HB_COMP_PARAM ); + pNew = hb_compExprSetOperand( hb_compExprNewPlus( pNew, HB_COMP_PARAM ), hb_compExprNewString( "}", 1, FALSE, HB_COMP_PARAM ), HB_COMP_PARAM ); pNew = hb_compExprNewMacro( pNew, 0, NULL, HB_COMP_PARAM ); HB_EXPR_USE( pNew, HB_EA_PUSH_PCODE ); hb_compExprDelete( pNew, HB_COMP_PARAM ); @@ -585,7 +584,7 @@ static void hb_compExprCodeblockEarly( HB_EXPR_PTR pSelf, HB_COMP_DECL ) hb_compExprCodeblockPush( pSelf, FALSE, HB_COMP_PARAM ); cStr = pSelf->value.asCodeblock.string; - pNew = hb_compExprNewMacro( hb_compExprNewString( cStr, strlen( cStr ), HB_COMP_PARAM ), 0, NULL, HB_COMP_PARAM ); + pNew = hb_compExprNewMacro( hb_compExprNewString( cStr, strlen( cStr ), FALSE, HB_COMP_PARAM ), 0, NULL, HB_COMP_PARAM ); HB_EXPR_USE( pNew, HB_EA_PUSH_PCODE ); hb_compExprDelete( pNew, HB_COMP_PARAM ); HB_EXPR_PCODE0( hb_compCodeBlockStop ); @@ -884,35 +883,19 @@ static HB_EXPR_FUNC( hb_compExprUseRef ) else if( pExp->ExprType == HB_ET_ALIASVAR ) { char *szAlias = pExp->value.asAlias.pAlias->value.asSymbol; - if( szAlias[ 0 ] == 'M' && szAlias[ 1 ] == '\0' ) - { /* @M->variable */ - if( pExp->value.asAlias.pVar->ExprType == HB_ET_VARIABLE ) - { + int iLen = strlen( szAlias ); + if( ( iLen == 1 ) || ( iLen >= 4 && iLen <= 6 ) && + memcmp( szAlias, "MEMVAR", iLen ) == 0 && + pExp->value.asAlias.pVar->ExprType == HB_ET_VARIABLE ) + { /* @M-> @MEMVAR-> or @MEMVA-> or @MEMV-> */ #if !defined(HB_MACRO_SUPPORT) - HB_EXPR_PCODE2( hb_compGenVarPCode, HB_P_PUSHMEMVARREF, pExp->value.asAlias.pVar->value.asSymbol ); + HB_EXPR_PCODE2( hb_compGenVarPCode, HB_P_PUSHMEMVARREF, pExp->value.asAlias.pVar->value.asSymbol ); #else - HB_EXPR_PCODE2( hb_compMemvarGenPCode, HB_P_MPUSHMEMVARREF, pExp->value.asAlias.pVar->value.asSymbol ); + HB_EXPR_PCODE2( hb_compMemvarGenPCode, HB_P_MPUSHMEMVARREF, pExp->value.asAlias.pVar->value.asSymbol ); #endif - } - else /* @M->&l, @M->&l.1, @&m->l, etc. */ - hb_compErrorRefer( HB_COMP_PARAM, pSelf, szAlias ); } else - { - int iCmp = strncmp( szAlias, "MEMVAR", 4 ); - if( iCmp == 0 ) - iCmp = strncmp( szAlias, "MEMVAR", strlen( szAlias ) ); - if( iCmp == 0 && pExp->value.asAlias.pVar->ExprType == HB_ET_VARIABLE ) - { /* @MEMVAR-> or @MEMVA-> or @MEMV-> */ -#if !defined(HB_MACRO_SUPPORT) - HB_EXPR_PCODE2( hb_compGenVarPCode, HB_P_PUSHMEMVARREF, pExp->value.asAlias.pVar->value.asSymbol ); -#else - HB_EXPR_PCODE2( hb_compMemvarGenPCode, HB_P_MPUSHMEMVARREF, pExp->value.asAlias.pVar->value.asSymbol ); -#endif - } - else - hb_compErrorRefer( HB_COMP_PARAM, pSelf, szAlias ); - } + hb_compErrorRefer( HB_COMP_PARAM, pSelf, szAlias ); } else if( pExp->ExprType == HB_ET_SEND ) { @@ -1426,14 +1409,12 @@ static HB_EXPR_FUNC( hb_compExprUseMacro ) */ #if ! defined( HB_MACRO_SUPPORT ) BOOL bUseTextSubst; - char *szDupl; - szDupl = hb_strupr( hb_strdup( pSelf->value.asMacro.szMacro ) ); - - if( !hb_compExprIsValidMacro( szDupl, &bUseTextSubst, HB_COMP_PARAM ) ) + if( !hb_compExprIsValidMacro( pSelf->value.asMacro.szMacro, + strlen( pSelf->value.asMacro.szMacro ), + &bUseTextSubst, HB_COMP_PARAM ) ) { hb_compErrorMacro( HB_COMP_PARAM, pSelf->value.asMacro.szMacro ); } - hb_xfree( szDupl ); #endif HB_EXPR_PCODE2( hb_compGenPushString, pSelf->value.asMacro.szMacro, strlen(pSelf->value.asMacro.szMacro) + 1 ); } @@ -1518,18 +1499,15 @@ static HB_EXPR_FUNC( hb_compExprUseMacro ) * be compiled after text susbstitution */ #if ! defined( HB_MACRO_SUPPORT ) - BOOL bUseTextSubst; - char *szDupl; - szDupl = hb_strupr( hb_strdup( pSelf->value.asMacro.szMacro ) ); - - if( !hb_compExprIsValidMacro( szDupl, &bUseTextSubst, HB_COMP_PARAM ) ) + if( !hb_compExprIsValidMacro( pSelf->value.asMacro.szMacro, + strlen( pSelf->value.asMacro.szMacro ), + &bUseTextSubst, HB_COMP_PARAM ) ) { hb_compErrorMacro( HB_COMP_PARAM, pSelf->value.asMacro.szMacro ); } - hb_xfree( szDupl ); #endif - HB_EXPR_PCODE2( hb_compGenPushString, pSelf->value.asMacro.szMacro, strlen(pSelf->value.asMacro.szMacro) + 1 ); + HB_EXPR_PCODE2( hb_compGenPushString, pSelf->value.asMacro.szMacro, strlen( pSelf->value.asMacro.szMacro ) + 1 ); } } /* compile & run - macro compiler will generate pcode to pop a value diff --git a/harbour/include/hbexprc.c b/harbour/include/hbexprc.c index 2a05258298..11535700dc 100644 --- a/harbour/include/hbexprc.c +++ b/harbour/include/hbexprc.c @@ -673,65 +673,66 @@ ULONG hb_compExprReduceList( HB_EXPR_PTR pExpr, HB_COMP_DECL ) return ulCnt; } -BOOL hb_compExprIsValidMacro( char * szText, BOOL *pbUseTextSubst, HB_COMP_DECL ) +BOOL hb_compExprIsValidMacro( char * szText, ULONG ulLen, BOOL *pfUseTextSubst, HB_COMP_DECL ) { - char * pTmp = szText; - BOOL bTextSubst; - BOOL bMacroText = TRUE; + BOOL fValid = TRUE; - *pbUseTextSubst = FALSE; /* no valid macro expression */ - while( ((pTmp = strchr( pTmp, '&' )) != NULL) && bMacroText ) + *pfUseTextSubst = FALSE; /* no valid macro expression */ + + while( ulLen-- && fValid ) { - /* Check if macro operator is used inside a string - * Macro operator is ignored if it is the last char or - * next char is '(' e.g. "this is &(ignored)" - * (except if strict Clipper compatibility mode is enabled) - * - * NOTE: This uses _a-zA-Z pattern to check for - * beginning of a variable name - */ - - if( ! HB_COMP_ISSUPPORTED(HB_COMPFLAG_HARBOUR) ) - *pbUseTextSubst = TRUE; /* always macro substitution in Clipper */ - - ++pTmp; - bTextSubst = ( *pTmp == '_' || (*pTmp >= 'A' && *pTmp <= 'Z') || (*pTmp >= 'a' && *pTmp <= 'z') ); - /* NOTE: All variables are assumed memvars in macro compiler - - * there is no need to check for a valid name - */ - if( bTextSubst ) + if( *szText++ == '&' && ulLen ) { + char ch = *szText; + /* Check if macro operator is used inside a string + * Macro operator is ignored if it is the last char or + * next char is '(' e.g. "this is &(ignored)" + * (except if strict Clipper compatibility mode is enabled) + * + * NOTE: This uses _a-zA-Z pattern to check for + * beginning of a variable name + */ + + if( ch == '_' || ( ch >= 'A' && ch <= 'Z' ) || ( ch >= 'a' && ch <= 'z' ) ) #if defined( HB_MACRO_SUPPORT ) - HB_SYMBOL_UNUSED( bMacroText ); - *pbUseTextSubst = TRUE; /* valid macro expression */ - return TRUE; /*there is no need to check all '&' occurences */ + { + HB_SYMBOL_UNUSED( HB_COMP_PARAM ); + *pfUseTextSubst = TRUE; /* valid macro expression */ + return TRUE; /*there is no need to check all '&' occurences */ + } #else - /* There is a valid character after '&' that can be used in - * variable name - check if the whole variable name is valid - * (local, static and field variable names are invalid because - * they are not visible at runtime) - */ - char * pStart = pTmp; - char cSave; + { + char szSymName[ HB_SYMBOL_NAME_LEN + 1 ]; + int iSize = 0; + do + { + if( ch >= 'a' && ch <= 'z' ) + szSymName[ iSize++ ] = ch - ( 'a' - 'A' ); + else if( ch == '_' || ( ch >= 'A' && ch <= 'Z' ) || + ( ch >= '0' && ch <= '9' ) ) + szSymName[ iSize++ ] = ch; + else + break; + ch = *(++szText); + } + while( --ulLen && iSize < HB_SYMBOL_NAME_LEN ); + szSymName[ iSize ] = '\0'; - /* NOTE: This uses _a-zA-Z0-9 pattern to check for - * variable name - */ - while( *pTmp && (*pTmp == '_' || (*pTmp >= 'A' && *pTmp <= 'Z') || (*pTmp >= 'a' && *pTmp <= 'z') || (*pTmp >= '0' && *pTmp <= '9')) ) - ++pTmp; - - cSave = *pTmp; - *pTmp = '\0'; - - bMacroText &= hb_compIsValidMacroVar( pStart, HB_COMP_PARAM ); - *pTmp = cSave; + /* NOTE: All variables are assumed memvars in macro compiler - + * there is no need to check for a valid name but to be Clipper + * compatible we should check if local, static or field name + * is not use and generate error in such case + */ + *pfUseTextSubst = TRUE; + fValid = hb_compIsValidMacroVar( szSymName, HB_COMP_PARAM ); + } + else if( ! HB_COMP_ISSUPPORTED(HB_COMPFLAG_HARBOUR) ) + *pfUseTextSubst = TRUE; /* always macro substitution in Clipper */ #endif } - *pbUseTextSubst |= bTextSubst; } - HB_SYMBOL_UNUSED( HB_COMP_PARAM ); /* to suppress BCC warning */ - return bMacroText; + return fValid; } /* Reduces the list of expressions diff --git a/harbour/include/hbexprop.h b/harbour/include/hbexprop.h index 6b33cd98b7..e03eafd32d 100644 --- a/harbour/include/hbexprop.h +++ b/harbour/include/hbexprop.h @@ -86,7 +86,7 @@ extern HB_EXPR_PTR hb_compExprNewNil( HB_COMP_DECL ); extern HB_EXPR_PTR hb_compExprNewDouble( double, BYTE, BYTE, HB_COMP_DECL ); extern HB_EXPR_PTR hb_compExprNewLong( HB_LONG, HB_COMP_DECL ); extern HB_EXPR_PTR hb_compExprNewDate( HB_LONG, HB_COMP_DECL ); -extern HB_EXPR_PTR hb_compExprNewString( char *, ULONG, HB_COMP_DECL ); +extern HB_EXPR_PTR hb_compExprNewString( char *, ULONG, BOOL, HB_COMP_DECL ); extern HB_EXPR_PTR hb_compExprNewLogical( int, HB_COMP_DECL ); extern HB_EXPR_PTR hb_compExprNewSelf( HB_COMP_DECL ); extern HB_EXPR_PTR hb_compExprNewCodeBlock( char *, BOOL, BOOL, HB_COMP_DECL ); @@ -170,7 +170,7 @@ extern BOOL hb_compExprReduceCHR( HB_EXPR_PTR, HB_COMP_DECL ); extern BOOL hb_compExprReduceLEN( HB_EXPR_PTR, HB_COMP_DECL ); extern BOOL hb_compExprReduceASC( HB_EXPR_PTR, HB_COMP_DECL ); extern BOOL hb_compExprReduceSTOD( HB_EXPR_PTR pSelf, USHORT usCount, HB_COMP_DECL ); -extern BOOL hb_compExprIsValidMacro( char *, BOOL *, HB_COMP_DECL ); +extern BOOL hb_compExprIsValidMacro( char *, ULONG, BOOL *, HB_COMP_DECL ); extern void hb_compExprDelete( HB_EXPR_PTR, HB_COMP_DECL ); extern HB_EXPR_PTR hb_compExprSetOperand( HB_EXPR_PTR, HB_EXPR_PTR, HB_COMP_DECL ); extern HB_EXPR_PTR hb_compExprGenStatement( HB_EXPR_PTR, HB_COMP_DECL ); diff --git a/harbour/source/common/expropt1.c b/harbour/source/common/expropt1.c index cdc2790c96..d690bbe45b 100644 --- a/harbour/source/common/expropt1.c +++ b/harbour/source/common/expropt1.c @@ -423,15 +423,12 @@ HB_EXPR_PTR hb_compExprNewMacro( HB_EXPR_PTR pMacroExpr, * ? &var // this is OK * ? &var.ext // this is invalid */ - char *szDupl; BOOL bUseTextSubst; - - szDupl = hb_strupr( hb_strdup( szName ) ); - if( ! hb_compExprIsValidMacro( szDupl, &bUseTextSubst, HB_COMP_PARAM ) ) + if( ! hb_compExprIsValidMacro( szName, strlen( szName ), + &bUseTextSubst, HB_COMP_PARAM ) ) { hb_compErrorMacro( szName, HB_COMP_PARAM ); } - hb_xfree( szDupl ); } } else diff --git a/harbour/source/common/expropt2.c b/harbour/source/common/expropt2.c index c68e389cab..3ea87a7866 100644 --- a/harbour/source/common/expropt2.c +++ b/harbour/source/common/expropt2.c @@ -463,7 +463,10 @@ HB_EXPR_PTR hb_compExprReducePlus( HB_EXPR_PTR pSelf, HB_COMP_DECL ) { /* Do not reduce strings with the macro operator '&' */ - if( strchr(pLeft->value.asString.string, '&') == NULL ) + BOOL fSubst; + hb_compExprIsValidMacro( pLeft->value.asString.string, pLeft->ulLength, + &fSubst, HB_COMP_PARAM ); + if( !fSubst && pLeft->value.asString.string[ pLeft->ulLength - 1 ] != '&' ) { pSelf->ExprType = HB_ET_NONE; /* suppress deletion of operator components */ hb_compExprFree( pSelf, HB_COMP_PARAM ); diff --git a/harbour/source/common/hbstr.c b/harbour/source/common/hbstr.c index ec1a3eb3ad..5928dd4644 100644 --- a/harbour/source/common/hbstr.c +++ b/harbour/source/common/hbstr.c @@ -901,9 +901,11 @@ char * hb_strRemEscSeq( char *str, ULONG *pLen ) if( ul && *ptr >= '0' && *ptr <= '7' ) { ch = ( ch << 3 ) | ( *ptr++ - '0' ); + ++ulStripped; if( --ul && *ptr >= '0' && *ptr <= '7' ) { ch = ( ch << 3 ) | ( *ptr++ - '0' ); + ++ulStripped; --ul; } } @@ -920,6 +922,7 @@ char * hb_strRemEscSeq( char *str, ULONG *pLen ) ch = ch << 4 | ( *ptr++ - 'a' + 10 ); else break; + ++ulStripped; --ul; } break; diff --git a/harbour/source/compiler/complex.c b/harbour/source/compiler/complex.c index df71473b01..a4c82961ff 100644 --- a/harbour/source/compiler/complex.c +++ b/harbour/source/compiler/complex.c @@ -264,6 +264,23 @@ static char * hb_comp_tokenIdentifer( HB_COMP_DECL, PHB_PP_TOKEN pToken ) return pToken->value; } +static char * hb_comp_tokenString( YYSTYPE *yylval_ptr, HB_COMP_DECL, PHB_PP_TOKEN pToken ) +{ + yylval_ptr->valChar.length = pToken->len; + yylval_ptr->valChar.string = pToken->value; + yylval_ptr->valChar.dealloc = FALSE; + if( HB_PP_TOKEN_ALLOC( pToken->type ) ) + { + yylval_ptr->valChar.dealloc = ( ULONG ) pToken->len != strlen( pToken->value ); + pToken->value = hb_compIdentifierNew( HB_COMP_PARAM, pToken->value, + yylval_ptr->valChar.dealloc ); + if( !yylval_ptr->valChar.dealloc ) + yylval_ptr->valChar.string = pToken->value; + pToken->type |= HB_PP_TOKEN_STATIC; + } + return pToken->value; +} + //int hb_complex( YYSTYPE *yylval_ptr, HB_COMP_DECL ) int yylex( YYSTYPE *yylval_ptr, HB_COMP_DECL ) { @@ -271,7 +288,10 @@ int yylex( YYSTYPE *yylval_ptr, HB_COMP_DECL ) PHB_PP_TOKEN pToken = hb_pp_tokenGet( pLex->pPP ); if( !pToken || HB_COMP_PARAM->fExit ) + { + pLex->lasttok = NULL; return 0; + } pLex->lasttok = pToken->value; @@ -312,8 +332,7 @@ int yylex( YYSTYPE *yylval_ptr, HB_COMP_DECL ) case HB_PP_TOKEN_STRING: pLex->iState = LITERAL; - pLex->lasttok = yylval_ptr->string = - hb_comp_tokenIdentifer( HB_COMP_PARAM, pToken ); + pLex->lasttok = hb_comp_tokenString( yylval_ptr, HB_COMP_PARAM, pToken ); return LITERAL; case HB_PP_TOKEN_LOGICAL: @@ -349,8 +368,8 @@ int yylex( YYSTYPE *yylval_ptr, HB_COMP_DECL ) case WHILE: pLex->iState = LITERAL; hb_pp_tokenToString( pLex->pPP, pToken ); - pLex->lasttok = yylval_ptr->string = - hb_comp_tokenIdentifer( HB_COMP_PARAM, pToken ); + pLex->lasttok = hb_comp_tokenString( yylval_ptr, HB_COMP_PARAM, + pToken ); return LITERAL; default: diff --git a/harbour/source/compiler/gencli.c b/harbour/source/compiler/gencli.c index aeb9c3b9fb..e7cff5beef 100644 --- a/harbour/source/compiler/gencli.c +++ b/harbour/source/compiler/gencli.c @@ -59,13 +59,12 @@ typedef HB_GENC_FUNC_ * HB_GENC_FUNC_PTR; void hb_compGenILCode( HB_COMP_DECL, PHB_FNAME pFileName ) /* generates the IL output */ { char szFileName[ _POSIX_PATH_MAX ], * szVer; - PFUNCTION pFunc = HB_COMP_PARAM->functions.pFirst; - PCOMSYMBOL pSym = HB_COMP_PARAM->symbols.pFirst; + PFUNCTION pFunc = HB_COMP_PARAM->functions.pFirst; + PCOMSYMBOL pSym = HB_COMP_PARAM->symbols.pFirst; + PINLINE pInline; PCOMDECLARED pDeclared; PCOMCLASS pClass; FILE * yyc; /* file handle for IL output */ - PINLINE pInline = HB_COMP_PARAM->inlines.pFirst; - BOOL bIsPublicFunction ; BOOL bIsInitFunction ; BOOL bIsExitFunction ; diff --git a/harbour/source/compiler/harbour.c b/harbour/source/compiler/harbour.c index 72d1709a3f..ace66f052a 100644 --- a/harbour/source/compiler/harbour.c +++ b/harbour/source/compiler/harbour.c @@ -1082,19 +1082,15 @@ BOOL hb_compIsValidMacroVar( char * szVarName, HB_COMP_DECL ) ;/* hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_BAD_MACRO, szVarName, NULL );*/ else if( ! HB_COMP_PARAM->fStartProc ) { - if( hb_compMemvarGetPos( szVarName, HB_COMP_PARAM->functions.pLast ) == 0 ) - { - /* This is not a local MEMVAR - */ - if( hb_compFieldGetPos( szVarName, HB_COMP_PARAM->functions.pFirst ) > 0 ) - ; /*hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_BAD_MACRO, szVarName, NULL );*/ - else if( hb_compStaticGetPos( szVarName, HB_COMP_PARAM->functions.pFirst ) > 0 ) - ; /*hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_BAD_MACRO, szVarName, NULL );*/ - else - bValid = TRUE; /* undeclared variable */ - } - else + /* Is it a local MEMVAR ? */ + if( hb_compMemvarGetPos( szVarName, HB_COMP_PARAM->functions.pLast ) ) bValid = TRUE; + else if( hb_compFieldGetPos( szVarName, HB_COMP_PARAM->functions.pFirst ) > 0 ) + ; /*hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_BAD_MACRO, szVarName, NULL );*/ + else if( hb_compStaticGetPos( szVarName, HB_COMP_PARAM->functions.pFirst ) > 0 ) + ; /*hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_BAD_MACRO, szVarName, NULL );*/ + else + bValid = TRUE; /* undeclared variable */ } else bValid = TRUE; /* undeclared variable */ diff --git a/harbour/source/compiler/harbour.y b/harbour/source/compiler/harbour.y index b2b82a6ece..a742bbb2dd 100644 --- a/harbour/source/compiler/harbour.y +++ b/harbour/source/compiler/harbour.y @@ -93,15 +93,9 @@ static void hb_compDebugStart( void ) { }; HB_LONG lNumber; /* to hold a temporary long number */ BOOL bTrue; struct - { - int iNumber; /* to hold a number returned by lex */ - char * szValue; - } valInteger; - struct { HB_LONG lNumber; /* to hold a long number returned by lex */ UCHAR bWidth; /* to hold the width of the value */ - char * szValue; } valLong; struct { @@ -109,10 +103,15 @@ static void hb_compDebugStart( void ) { }; /* NOTE: Intentionally using "unsigned char" instead of "BYTE" */ UCHAR bWidth; /* to hold the width of the value */ UCHAR bDec; /* to hold the number of decimal points in the value */ - char * szValue; } valDouble; HB_EXPR_PTR asExpr; struct + { + char * string; + int length; + BOOL dealloc; + } valChar; + struct { char * string; int length; @@ -141,7 +140,7 @@ extern void yyerror( HB_COMP_DECL, char * ); /* parsing error management fun %} -%token FUNCTION PROCEDURE IDENTIFIER RETURN NIL NUM_DOUBLE INASSIGN NUM_INTEGER NUM_LONG +%token FUNCTION PROCEDURE IDENTIFIER RETURN NIL NUM_DOUBLE INASSIGN NUM_LONG %token LOCAL STATIC IIF IF ELSE ELSEIF END ENDIF LITERAL TRUEVALUE FALSEVALUE %token ANNOUNCE EXTERN INIT EXIT AND OR NOT PUBLIC EQ NE1 NE2 %token INC DEC ALIASOP DOCASE CASE OTHERWISE ENDCASE ENDDO MEMVAR @@ -184,12 +183,12 @@ extern void yyerror( HB_COMP_DECL, char * ); /* parsing error management fun %right '\n' ';' ',' /*the highest precedence*/ -%type IdentName IDENTIFIER LITERAL MACROVAR MACROTEXT CompTimeStr +%type IdentName IDENTIFIER MACROVAR MACROTEXT CompTimeStr %type DOIDENT WHILE +%type LITERAL %type NUM_DOUBLE -%type NUM_INTEGER %type NUM_LONG -%type NUM_DATE +%type NUM_DATE %type FunScope %type Params ParamList %type IfBegin VarList ExtVarList @@ -279,6 +278,7 @@ extern void yyerror( HB_COMP_DECL, char * ); /* parsing error management fun ForVar ForList ForExpr %destructor { hb_xfree( $$.string ); } CBSTART +%destructor { if( $$.dealloc ) hb_xfree( $$.string ); } LITERAL %% @@ -308,15 +308,32 @@ Source : Crlf | Source error Crlf { yyclearin; yyerrok; } ; -Line : LINE NUM_INTEGER LITERAL Crlf - | LINE NUM_INTEGER LITERAL '@' LITERAL Crlf /* Xbase++ style */ +Line : LINE NUM_LONG LITERAL Crlf + | LINE NUM_LONG LITERAL '@' LITERAL Crlf /* Xbase++ style */ ; ProcReq : PROCREQ CompTimeStr ')' Crlf { HB_COMP_PARAM->functions.pLast->bFlags &= ~ FUN_WITH_RETURN; } ; -CompTimeStr: LITERAL { hb_compAutoOpenAdd( HB_COMP_PARAM, $1 ); } - | LITERAL '+' LITERAL { char szFileName[ _POSIX_PATH_MAX + 1 ]; hb_strncat( hb_strncpy( szFileName, $1, _POSIX_PATH_MAX ), $3, _POSIX_PATH_MAX ); hb_compAutoOpenAdd( HB_COMP_PARAM, hb_compIdentifierNew( HB_COMP_PARAM, szFileName, TRUE ) ); } +CompTimeStr: LITERAL { + if( $1.dealloc ) + { + $1.string = hb_compIdentifierNew( HB_COMP_PARAM, $1.string, FALSE ); + $1.dealloc = FALSE; + } + hb_compAutoOpenAdd( HB_COMP_PARAM, $1.string ); + } + | LITERAL '+' LITERAL { + { + char szFileName[ _POSIX_PATH_MAX + 1 ]; + hb_strncat( hb_strncpy( szFileName, $1.string, _POSIX_PATH_MAX ), $3.string, _POSIX_PATH_MAX ); + hb_compAutoOpenAdd( HB_COMP_PARAM, hb_compIdentifierNew( HB_COMP_PARAM, szFileName, TRUE ) ); + if( $1.dealloc ) + hb_xfree( $1.string ); + if( $3.dealloc ) + hb_xfree( $3.string ); + } + } ; Function : FunScope FUNCTION IdentName { HB_COMP_PARAM->cVarType = ' '; hb_compFunctionAdd( HB_COMP_PARAM, $3, ( HB_SYMBOLSCOPE ) $1, 0 ); } Crlf {} @@ -383,13 +400,13 @@ Statement : ExecFlow { HB_COMP_PARAM->fDontGenLineNum = TRUE; } CrlfStmnt { else hb_compExprDelete( hb_compErrorSyntax( HB_COMP_PARAM, $1 ), HB_COMP_PARAM ); HB_COMP_PARAM->functions.pLast->bFlags &= ~ FUN_WITH_RETURN; - } + } | MacroExpr CrlfStmnt { if( HB_COMP_ISSUPPORTED( HB_COMPFLAG_XBASE ) ) hb_compExprDelete( hb_compExprGenStatement( $1, HB_COMP_PARAM ), HB_COMP_PARAM ); else hb_compExprDelete( hb_compErrorSyntax( HB_COMP_PARAM, $1 ), HB_COMP_PARAM ); HB_COMP_PARAM->functions.pLast->bFlags &= ~ FUN_WITH_RETURN; - } + } | PareExpList CrlfStmnt { hb_compExprDelete( hb_compExprGenStatement( $1, HB_COMP_PARAM ), HB_COMP_PARAM ); HB_COMP_PARAM->functions.pLast->bFlags &= ~ FUN_WITH_RETURN; } | ExprPreOp CrlfStmnt { hb_compExprDelete( hb_compExprGenStatement( $1, HB_COMP_PARAM ), HB_COMP_PARAM ); HB_COMP_PARAM->functions.pLast->bFlags &= ~ FUN_WITH_RETURN; } | ExprPostOp CrlfStmnt { hb_compExprDelete( hb_compExprGenStatement( $1, HB_COMP_PARAM ), HB_COMP_PARAM ); HB_COMP_PARAM->functions.pLast->bFlags &= ~ FUN_WITH_RETURN; } @@ -507,20 +524,18 @@ IdentName : IDENTIFIER { $$ = $1; } /* Numeric values */ NumValue : NUM_DOUBLE { $$ = hb_compExprNewDouble( $1.dNumber, $1.bWidth, $1.bDec, HB_COMP_PARAM ); } - | NUM_INTEGER { $$ = hb_compExprNewLong( $1.iNumber, HB_COMP_PARAM ); } | NUM_LONG { $$ = hb_compExprNewLong( $1.lNumber, HB_COMP_PARAM ); } ; DateValue : NUM_DATE { $$ = hb_compExprNewDate( $1.lNumber, HB_COMP_PARAM ); if( $1.lNumber == 0 ) { - hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_INVALID_DATE, $1.szValue, NULL ); + hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_INVALID_DATE, HB_COMP_PARAM->pLex->lasttok, NULL ); } } ; -NumAlias : NUM_INTEGER ALIASOP { $$ = hb_compExprNewLong( $1.iNumber, HB_COMP_PARAM ); } - | NUM_LONG ALIASOP { $$ = hb_compExprNewLong( $1.lNumber, HB_COMP_PARAM ); } +NumAlias : NUM_LONG ALIASOP { $$ = hb_compExprNewLong( $1.lNumber, HB_COMP_PARAM ); } | NUM_DOUBLE ALIASOP { $$ = hb_compErrorAlias( HB_COMP_PARAM, hb_compExprNewDouble( $1.dNumber, $1.bWidth, $1.bDec, HB_COMP_PARAM ) ); } ; @@ -535,8 +550,7 @@ NilAlias : NilValue ALIASOP { $$ = $1; } /* Literal string value */ LiteralValue : LITERAL { - ULONG len = strlen( $1 ); - $$ = hb_compExprNewString( $1, len, HB_COMP_PARAM ); + $$ = hb_compExprNewString( $1.string, $1.length, $1.dealloc, HB_COMP_PARAM ); } ; diff --git a/harbour/source/macro/macro.y b/harbour/source/macro/macro.y index 7db38d6e5f..6731d9543a 100644 --- a/harbour/source/macro/macro.y +++ b/harbour/source/macro/macro.y @@ -1,4 +1,4 @@ -%pure_parser +%pure-parser %parse-param { HB_MACRO_PTR pMacro } %lex-param { HB_MACRO_PTR pMacro } @@ -275,7 +275,7 @@ NilValue : NIL { $$ = hb_compExprNewNil( HB_COMP_PARAM ); } /* Literal string value */ -LiteralValue : LITERAL { $$ = hb_compExprNewString( $1, strlen($1), HB_COMP_PARAM ); } +LiteralValue : LITERAL { $$ = hb_compExprNewString( $1, strlen($1), FALSE, HB_COMP_PARAM ); } ; /* Logical value diff --git a/harbour/source/vm/macro.c b/harbour/source/vm/macro.c index ce4c87650d..c362842e1f 100644 --- a/harbour/source/vm/macro.c +++ b/harbour/source/vm/macro.c @@ -124,6 +124,8 @@ void hb_macroDelete( HB_MACRO_PTR pMacro ) hb_xfree( (void *) pMacro->pCodeInfo->pCode ); hb_xfree( (void *) pMacro->pCodeInfo ); + if( pMacro->pError ) + hb_errRelease( pMacro->pError ); if( pMacro->Flags & HB_MACRO_DEALLOCATE ) hb_xfree( pMacro ); } @@ -152,35 +154,22 @@ static BOOL hb_macroCheckParam( HB_ITEM_PTR pItem ) return bValid; } -/* It handles an error generated during macro evaluation - */ -static HB_ERROR_HANDLE( hb_macroErrorEvaluation ) -{ - HB_ITEM_PTR pResult = hb_itemDo( ErrorInfo->ErrorBlock, 1, ErrorInfo->Error ); - - /* In a special case when QUIT is requested then there is no return - * to code where macro evaluation was called. We have to - * release all used memory here. - */ - if( hb_vmRequestQuery() == HB_QUIT_REQUESTED ) - hb_macroDelete( ( HB_MACRO_PTR ) ErrorInfo->Cargo ); - - return pResult; -} - /* It handles an error generated during checking of expression type */ static HB_ERROR_HANDLE( hb_macroErrorType ) { HB_MACRO_PTR pMacro = ( HB_MACRO_PTR ) ErrorInfo->Cargo; - /* copy error object for later diagnostic usage */ + /* copy error object for later diagnostic usage */ + if( pMacro->pError ) + hb_itemRelease( pMacro->pError ); pMacro->pError = hb_itemNew( ErrorInfo->Error ); pMacro->status &= ~HB_MACRO_CONT; - /* ignore rest of compiled code - */ + + /* ignore rest of compiled code */ hb_vmRequestEndProc(); - return NULL; /* ignore this error */ + + return NULL; /* ignore this error */ } @@ -196,45 +185,21 @@ void hb_macroRun( HB_MACRO_PTR pMacro ) hb_vmExecute( pMacro->pCodeInfo->pCode, NULL ); } -/* evaluate a macro-cmpiled code and discard it - */ -static void hb_macroEvaluate( HB_MACRO_PTR pMacro ) -{ - HB_ERROR_INFO struErr; - HB_ERROR_INFO_PTR pOld; - - struErr.Func = hb_macroErrorEvaluation; - struErr.Cargo = ( void * ) pMacro; - pOld = hb_errorHandler( &struErr ); - hb_macroRun( pMacro ); - hb_errorHandler( pOld ); - hb_macroDelete( pMacro ); -} - - static void hb_macroSyntaxError( HB_MACRO_PTR pMacro ) { - HB_ITEM_PTR pResult; - HB_ITEM_PTR pError = NULL; - HB_TRACE(HB_TR_DEBUG, ("hb_macroSyntaxError(%p)", pMacro)); - if( pMacro ) + if( pMacro && pMacro->pError ) { HB_TRACE(HB_TR_DEBUG, ("hb_macroSyntaxError.(%s)", pMacro->string)); - pError = pMacro->pError; - hb_macroDelete( pMacro ); - } - - if( pError ) - { - hb_errLaunch( pError ); - hb_errRelease( pError ); + hb_errLaunch( pMacro->pError ); + hb_errRelease( pMacro->pError ); + pMacro->pError = NULL; } else { - pResult = hb_errRT_BASE_Subst( EG_SYNTAX, 1449, NULL, "&", 0 ); + PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_SYNTAX, 1449, NULL, "&", 0 ); if( pResult ) { @@ -531,22 +496,20 @@ void hb_macroGetValue( HB_ITEM_PTR pItem, BYTE iContext, BYTE flags ) hb_stackPop(); /* remove compiled string */ if( iStatus == HB_MACRO_OK && ( struMacro.status & HB_MACRO_CONT ) ) { - hb_macroEvaluate( &struMacro ); + hb_macroRun( &struMacro ); if( iContext ) { if( iContext == HB_P_MACROPUSHLIST ) - { hb_vmPushLong( struMacro.uiListElements + 1 ); - } else if( iContext == HB_P_MACROPUSHINDEX ) - { hb_vmPushLong( struMacro.uiListElements ); - } } } else hb_macroSyntaxError( &struMacro ); + + hb_macroDelete( &struMacro ); } } @@ -573,11 +536,11 @@ void hb_macroSetValue( HB_ITEM_PTR pItem, BYTE flags ) hb_stackPop(); /* remove compiled string */ if( iStatus == HB_MACRO_OK && ( struMacro.status & HB_MACRO_CONT ) ) - { - hb_macroEvaluate( &struMacro ); - } + hb_macroRun( &struMacro ); else hb_macroSyntaxError( &struMacro ); + + hb_macroDelete( &struMacro ); } } @@ -623,11 +586,11 @@ static void hb_macroUseAliased( HB_ITEM_PTR pAlias, HB_ITEM_PTR pVar, int iFlag, hb_stackPop(); /* remove compiled alias */ if( iStatus == HB_MACRO_OK && ( struMacro.status & HB_MACRO_CONT ) ) - { - hb_macroEvaluate( &struMacro ); - } + hb_macroRun( &struMacro ); else hb_macroSyntaxError( &struMacro ); + + hb_macroDelete( &struMacro ); } else if( hb_macroCheckParam( pVar ) ) { @@ -647,11 +610,11 @@ static void hb_macroUseAliased( HB_ITEM_PTR pAlias, HB_ITEM_PTR pVar, int iFlag, hb_stackPop(); /* remove compiled string */ if( iStatus == HB_MACRO_OK && ( struMacro.status & HB_MACRO_CONT ) ) - { - hb_macroEvaluate( &struMacro ); - } + hb_macroRun( &struMacro ); else hb_macroSyntaxError( &struMacro ); + + hb_macroDelete( &struMacro ); } } @@ -718,7 +681,6 @@ HB_MACRO_PTR hb_macroCompile( char * szString ) if( ! ( iStatus == HB_MACRO_OK && ( pMacro->status & HB_MACRO_CONT ) ) ) { hb_macroDelete( pMacro ); - hb_xfree( pMacro ); pMacro = NULL; } @@ -893,9 +855,6 @@ char * hb_macroGetType( HB_ITEM_PTR pItem ) else szType = "UE"; /* syntax error during compilation */ - if( struMacro.pError ) - hb_itemRelease( struMacro.pError ); - struMacro.pError = NULL; hb_macroDelete( &struMacro ); } else