diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 74ce0d5c58..41d51410ce 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,27 @@ past entries belonging to author(s): Viktor Szakats. */ +2010-02-27 11:05 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/src/vm/macro.c + * minor simplification + + * harbour/src/common/reserved.c + * minor cleanup + + * harbour/src/vm/eval.c + * inherit execution context (OOP scope) in HB_EXECFROMARRAY() function + + * harbour/include/hbcomp.h + * harbour/include/hbcompdf.h + + harbour/src/common/funcid.c + * harbour/src/common/Makefile + + added new [macro]compiler function: hb_compGetFuncID() which can be + used for function name hashing reducing strcmp() comparisons + + * harbour/include/hbexpra.c + * harbour/include/hbexprb.c + % use hb_compGetFuncID() to improve code for HB_ET_FUNCALL expressions + 2010-02-27 10:03 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) * contrib/hbsqlit3/hbsqlit3.c % Deleted unnecessary cast. diff --git a/harbour/include/hbcomp.h b/harbour/include/hbcomp.h index fbcef4dc03..3b970cd425 100644 --- a/harbour/include/hbcomp.h +++ b/harbour/include/hbcomp.h @@ -139,10 +139,11 @@ extern int hb_compVariableScope( HB_COMP_DECL, const char * ); #define FUN_FILE_FIRST 0x0100 /* 1-st real or pseudo function in compiled .prg module */ #define FUN_ATTACHED 0x0200 /* function attached to function list */ -extern void hb_compFunctionAdd( HB_COMP_DECL, const char * szFunName, HB_SYMBOLSCOPE cScope, int iType ); /* starts a new Clipper language function definition */ -extern HB_BOOL hb_compFunCallCheck( HB_COMP_DECL, const char *, int ); -extern PINLINE hb_compInlineAdd( HB_COMP_DECL, const char * szFunName, int iLine ); -extern void hb_compFunctionMarkStatic( HB_COMP_DECL, const char * szFunName ); +extern void hb_compFunctionAdd( HB_COMP_DECL, const char * szFunName, HB_SYMBOLSCOPE cScope, int iType ); /* starts a new Clipper language function definition */ +extern PINLINE hb_compInlineAdd( HB_COMP_DECL, const char * szFunName, int iLine ); +extern void hb_compFunctionMarkStatic( HB_COMP_DECL, const char * szFunName ); +extern HB_FUNC_ID hb_compGetFuncID( const char * szFuncName ); +extern HB_BOOL hb_compFunCallCheck( HB_COMP_DECL, const char *, int ); extern PHB_VARTYPE hb_compVarTypeNew( HB_COMP_DECL, char cVarType, const char * szFromClass ); extern void hb_compVariableAdd( HB_COMP_DECL, const char * szVarName, PHB_VARTYPE pVarType ); /* add a new param, local, static variable to a function definition or a public or private */ diff --git a/harbour/include/hbcompdf.h b/harbour/include/hbcompdf.h index 75e2a31dd2..646d6cba3c 100644 --- a/harbour/include/hbcompdf.h +++ b/harbour/include/hbcompdf.h @@ -247,6 +247,41 @@ typedef enum #define HB_EXPR_COUNT ( HB_EO_PREDEC + 1 ) +typedef enum +{ + HB_F_UDF = 0, + HB_F_AT, + HB_F_ASC, + HB_F_CHR, + HB_F_LEN, + HB_F_EMPTY, + HB_F_UPPER, + HB_F_INT, + HB_F_MAX, + HB_F_MIN, + HB_F_STOD, + HB_F_STOT, + HB_F_DTOS, + HB_F_CTOD, + HB_F_EVAL, + HB_F_BITAND, + HB_F_BITOR, + HB_F_BITXOR, + HB_F_BITSET, + HB_F_BITRESET, + HB_F_BITSHIFT, + HB_F_BITTEST, + HB_F_BITNOT, + HB_F_ARRAYTOPARAMS, + HB_F_I18N_GETTEXT, + HB_F_I18N_GETTEXT_STRICT, + HB_F_I18N_GETTEXT_NOOP, + HB_F_I18N_NGETTEXT, + HB_F_I18N_NGETTEXT_STRICT, + HB_F_I18N_NGETTEXT_NOOP, + HB_F__GET_ +} HB_FUNC_ID; + typedef HB_USHORT HB_EXPRTYPE; typedef struct HB_EXPR_ @@ -310,6 +345,7 @@ typedef struct HB_EXPR_ { struct HB_EXPR_ * pFunName; /* function name */ struct HB_EXPR_ * pParms; /* function call parameters */ + HB_FUNC_ID funcid; } asFunCall; struct { diff --git a/harbour/include/hbexpra.c b/harbour/include/hbexpra.c index 4b41946004..4af38b0779 100644 --- a/harbour/include/hbexpra.c +++ b/harbour/include/hbexpra.c @@ -117,7 +117,8 @@ HB_EXPR_PTR hb_macroExprNewFunCall( HB_EXPR_PTR pName, HB_EXPR_PTR pParms, HB_CO HB_EXPR_PTR hb_compExprNewFunCall( HB_EXPR_PTR pName, HB_EXPR_PTR pParms, HB_COMP_DECL ) #endif { - HB_EXPR_PTR pExpr = NULL; + HB_FUNC_ID funcID = HB_F_UDF; + HB_EXPR_PTR pExpr; if( pName->ExprType == HB_ET_FUNNAME ) { @@ -128,70 +129,67 @@ HB_EXPR_PTR hb_compExprNewFunCall( HB_EXPR_PTR pName, HB_EXPR_PTR pParms, HB_COM * at runtime - in this case pName is an expression of HB_ET_MACRO type * e.g. &MyVar() */ - int iLen; HB_TRACE(HB_TR_DEBUG, ("hb_compExprNewFunCall(%s)", pName->value.asSymbol)); - iLen = strlen( pName->value.asSymbol ); + funcID = hb_compGetFuncID( pName->value.asSymbol ); #if !defined( HB_MACRO_SUPPORT ) && defined( HB_USE_ENUM_FUNCTIONS ) - if( iLen > 7 && memcmp( "HB_ENUM", pName->value.asSymbol, 7 ) == 0 ) { - char * szMessage = NULL; - - if( iLen == 12 && memcmp( "INDEX", pName->value.asSymbol + 7, 5 ) == 0 ) - szMessage = "__ENUMINDEX"; - else if( iLen == 12 && memcmp( "VALUE", pName->value.asSymbol + 7, 5 ) == 0 ) - szMessage = "__ENUMVALUE"; - else if( iLen == 11 && memcmp( "BASE", pName->value.asSymbol + 7, 4 ) == 0 ) - szMessage = "__ENUMBASE"; - else if( iLen == 10 && memcmp( "KEY", pName->value.asSymbol + 7, 3 ) == 0 ) - szMessage = "__ENUMKEY"; - - if( szMessage ) + int iLen = strlen( pName->value.asSymbol ); + if( iLen >= 10 && i <= 12 && memcmp( "HB_ENUM", pName->value.asSymbol, 7 ) == 0 ) { - int iCount = ( int ) hb_compExprParamListLen( pParms ); - char * szName = NULL; + char * szMessage = NULL; - if( iCount == 0 ) + if( iLen == 12 && memcmp( "INDEX", pName->value.asSymbol + 7, 5 ) == 0 ) + szMessage = "__ENUMINDEX"; + else if( iLen == 12 && memcmp( "VALUE", pName->value.asSymbol + 7, 5 ) == 0 ) + szMessage = "__ENUMVALUE"; + else if( iLen == 11 && memcmp( "BASE", pName->value.asSymbol + 7, 4 ) == 0 ) + szMessage = "__ENUMBASE"; + else if( iLen == 10 && memcmp( "KEY", pName->value.asSymbol + 7, 3 ) == 0 ) + szMessage = "__ENUMKEY"; + + if( szMessage ) { - HB_ENUMERATOR_PTR pForVar, pEnumVar = NULL; - pForVar = HB_COMP_PARAM->functions.pLast->pEnum; - if( pForVar ) + int iCount = ( int ) hb_compExprParamListLen( pParms ); + char * szName = NULL; + + if( iCount == 0 ) { - while( pForVar ) + HB_ENUMERATOR_PTR pForVar, pEnumVar = NULL; + pForVar = HB_COMP_PARAM->functions.pLast->pEnum; + if( pForVar ) { - if( pForVar->bForEach ) - pEnumVar = pForVar; - pForVar = pForVar->pNext; + while( pForVar ) + { + if( pForVar->bForEach ) + pEnumVar = pForVar; + pForVar = pForVar->pNext; + } + if( pEnumVar ) + szName = pEnumVar->szName; } - if( pEnumVar ) - szName = pEnumVar->szName; + } + else if( iCount == 1 ) + { + if( pParms->value.asList.pExprList->ExprType == HB_ET_VARIABLE || + pParms->value.asList.pExprList->ExprType == HB_ET_VARREF ) + szName = pParms->value.asList.pExprList->value.asSymbol; + } + if( szName ) + { + HB_COMP_EXPR_DELETE( pParms ); + HB_COMP_EXPR_DELETE( pName ); + return hb_compExprNewMethodObject( + hb_compExprNewSend( szMessage, HB_COMP_PARAM ), + hb_compExprNewVar( szName, HB_COMP_PARAM ) ); } } - else if( iCount == 1 ) - { - if( pParms->value.asList.pExprList->ExprType == HB_ET_VARIABLE || - pParms->value.asList.pExprList->ExprType == HB_ET_VARREF ) - szName = pParms->value.asList.pExprList->value.asSymbol; - } - if( szName ) - { - HB_COMP_EXPR_DELETE( pParms ); - HB_COMP_EXPR_DELETE( pName ); - return hb_compExprNewMethodObject( - hb_compExprNewSend( szMessage, HB_COMP_PARAM ), - hb_compExprNewVar( szName, HB_COMP_PARAM ) ); - } } - } else #endif - if( hb_compExprParamListLen( pParms ) == 0 ) - { - /* nothing to do, both EVAL and _GET_ below need parameters */ - } - else if( iLen == 4 && memcmp( "EVAL", pName->value.asSymbol, 4 ) == 0 ) + if( funcID == HB_F_EVAL && hb_compExprParamListLen( pParms ) != 0 ) { HB_EXPR_PTR pEval; @@ -211,7 +209,7 @@ HB_EXPR_PTR hb_compExprNewFunCall( HB_EXPR_PTR pName, HB_EXPR_PTR pParms, HB_COM HB_COMP_EXPR_DELETE( pName ); return pEval; } - else if( iLen == 5 && memcmp( "_GET_", pName->value.asSymbol, 5 ) == 0 ) + else if( funcID == HB_F__GET_ && hb_compExprParamListLen( pParms ) != 0 ) { /* Reserved Clipper function used to handle GET variables */ @@ -447,12 +445,10 @@ HB_EXPR_PTR hb_compExprNewFunCall( HB_EXPR_PTR pName, HB_EXPR_PTR pParms, HB_COM } #endif - if( pExpr == NULL ) - { - pExpr = HB_COMP_EXPR_NEW( HB_ET_FUNCALL ); - pExpr->value.asFunCall.pParms = pParms; - pExpr->value.asFunCall.pFunName = pName; - } + pExpr = HB_COMP_EXPR_NEW( HB_ET_FUNCALL ); + pExpr->value.asFunCall.pParms = pParms; + pExpr->value.asFunCall.pFunName = pName; + pExpr->value.asFunCall.funcid = funcID; return pExpr; } diff --git a/harbour/include/hbexprb.c b/harbour/include/hbexprb.c index 005f2304f6..18199f5b0d 100644 --- a/harbour/include/hbexprb.c +++ b/harbour/include/hbexprb.c @@ -1716,94 +1716,84 @@ static HB_EXPR_FUNC( hb_compExprUseFunCall ) if( pSelf->value.asFunCall.pFunName->ExprType == HB_ET_FUNNAME ) { - HB_EXPR_PTR pName = pSelf->value.asFunCall.pFunName; HB_EXPR_PTR pParms = pSelf->value.asFunCall.pParms; HB_USHORT usCount = ( HB_USHORT ) hb_compExprParamListLen( pParms ); #ifndef HB_MACRO_SUPPORT - if( hb_compFunCallCheck( HB_COMP_PARAM, pName->value.asSymbol, usCount ) ) + if( hb_compFunCallCheck( HB_COMP_PARAM, pSelf->value.asFunCall.pFunName->value.asSymbol, usCount ) ) #endif { - if( strcmp( "AT", pName->value.asSymbol ) == 0 ) + switch( pSelf->value.asFunCall.funcid ) { - if( usCount == 2 ) - hb_compExprReduceAT( pSelf, HB_COMP_PARAM ); - } - else if( strcmp( "ASC", pName->value.asSymbol ) == 0 ) - { - if( usCount ) - hb_compExprReduceASC( pSelf, HB_COMP_PARAM ); - } - else if( strcmp( "CHR", pName->value.asSymbol ) == 0 ) - { - if( usCount ) - hb_compExprReduceCHR( pSelf, HB_COMP_PARAM ); - } - else if( strcmp( "LEN", pName->value.asSymbol ) == 0 ) - { - if( usCount ) - hb_compExprReduceLEN( pSelf, HB_COMP_PARAM ); - } - else if( strcmp( "UPPER", pName->value.asSymbol ) == 0 ) - { - if( usCount ) - hb_compExprReduceUPPER( pSelf, HB_COMP_PARAM ); - } - else if( strcmp( "EMPTY", pName->value.asSymbol ) == 0 ) - { - if( usCount && HB_SUPPORT_HARBOUR ) - hb_compExprReduceEMPTY( pSelf, HB_COMP_PARAM ); - } - else if( strcmp( "INT", pName->value.asSymbol ) == 0 ) - { - if( usCount == 1 && HB_SUPPORT_HARBOUR ) - hb_compExprReduceINT( pSelf, HB_COMP_PARAM ); - } - else if( strcmp( "MIN", pName->value.asSymbol ) == 0 ) - { - if( usCount == 2 && HB_SUPPORT_HARBOUR ) - hb_compExprReduceMIN( pSelf, HB_COMP_PARAM ); - } - else if( strcmp( "MAX", pName->value.asSymbol ) == 0 ) - { - if( usCount == 2 && HB_SUPPORT_HARBOUR ) - hb_compExprReduceMAX( pSelf, HB_COMP_PARAM ); - } - else if( strcmp( "STOD", pName->value.asSymbol ) == 0 || - strcmp( "HB_STOD", pName->value.asSymbol ) == 0 ) - { - if( usCount < 2 && HB_SUPPORT_HARBOUR ) - hb_compExprReduceSTOD( pSelf, usCount, HB_COMP_PARAM ); - } - else if( strcmp( "HB_STOT", pName->value.asSymbol ) == 0 ) - { - hb_compExprReduceSTOT( pSelf, usCount, HB_COMP_PARAM ); - } - else if( strcmp( "DTOS", pName->value.asSymbol ) == 0 ) - { - if( usCount == 1 ) - hb_compExprReduceDTOS( pSelf, HB_COMP_PARAM ); - } - else if( strcmp( "CTOD", pName->value.asSymbol ) == 0 ) - { - if( usCount && HB_SUPPORT_HARBOUR ) - hb_compExprReduceCTOD( pSelf, HB_COMP_PARAM ); - } - else if( strncmp( "HB_BIT", pName->value.asSymbol, 6 ) == 0 && - usCount && pParms->value.asList.pExprList->ExprType == HB_ET_NUMERIC ) - { - HB_EXPR_PTR pArg = pParms->value.asList.pExprList; - HB_MAXINT lResult = 0; - HB_BOOL fOptimize = HB_FALSE, fBool = HB_FALSE; + case HB_F_AT: + if( usCount == 2 ) + hb_compExprReduceAT( pSelf, HB_COMP_PARAM ); + break; + case HB_F_ASC: + if( usCount ) + hb_compExprReduceASC( pSelf, HB_COMP_PARAM ); + break; + case HB_F_CHR: + if( usCount ) + hb_compExprReduceCHR( pSelf, HB_COMP_PARAM ); + break; + case HB_F_LEN: + if( usCount ) + hb_compExprReduceLEN( pSelf, HB_COMP_PARAM ); + break; + case HB_F_UPPER: + if( usCount ) + hb_compExprReduceUPPER( pSelf, HB_COMP_PARAM ); + break; - if( usCount >= 2 ) - { - if( pArg->pNext->ExprType == HB_ET_NUMERIC ) + case HB_F_EMPTY: + if( usCount && HB_SUPPORT_HARBOUR ) + hb_compExprReduceEMPTY( pSelf, HB_COMP_PARAM ); + break; + case HB_F_INT: + if( usCount == 1 && HB_SUPPORT_HARBOUR ) + hb_compExprReduceINT( pSelf, HB_COMP_PARAM ); + break; + case HB_F_MAX: + if( usCount == 2 && HB_SUPPORT_HARBOUR ) + hb_compExprReduceMAX( pSelf, HB_COMP_PARAM ); + break; + case HB_F_MIN: + if( usCount == 2 && HB_SUPPORT_HARBOUR ) + hb_compExprReduceMIN( pSelf, HB_COMP_PARAM ); + break; + case HB_F_STOD: + if( usCount < 2 && HB_SUPPORT_HARBOUR ) + hb_compExprReduceSTOD( pSelf, usCount, HB_COMP_PARAM ); + break; + case HB_F_STOT: + hb_compExprReduceSTOT( pSelf, usCount, HB_COMP_PARAM ); + break; + case HB_F_DTOS: + if( usCount == 1 ) + hb_compExprReduceDTOS( pSelf, HB_COMP_PARAM ); + break; + case HB_F_CTOD: + if( usCount && HB_SUPPORT_HARBOUR ) + hb_compExprReduceCTOD( pSelf, HB_COMP_PARAM ); + break; + + case HB_F_BITAND: + case HB_F_BITOR: + case HB_F_BITXOR: + case HB_F_BITSET: + case HB_F_BITRESET: + case HB_F_BITSHIFT: + if( usCount >= 2 && + pParms->value.asList.pExprList->ExprType == HB_ET_NUMERIC && + pParms->value.asList.pExprList->pNext->ExprType == HB_ET_NUMERIC ) { - if( strcmp( "AND", pName->value.asSymbol + 6 ) == 0 ) + HB_EXPR_PTR pArg = pParms->value.asList.pExprList; + HB_MAXINT lResult = hb_compExprAsLongNum( pArg ); + HB_BOOL fOptimize = HB_TRUE; + + if( pSelf->value.asFunCall.funcid == HB_F_BITAND ) { - fOptimize = HB_TRUE; - lResult = hb_compExprAsLongNum( pArg ); while( --usCount ) { pArg = pArg->pNext; @@ -1815,10 +1805,8 @@ static HB_EXPR_FUNC( hb_compExprUseFunCall ) lResult &= hb_compExprAsLongNum( pArg ); } } - else if( strcmp( "OR", pName->value.asSymbol + 6 ) == 0 ) + else if( pSelf->value.asFunCall.funcid == HB_F_BITOR ) { - fOptimize = HB_TRUE; - lResult = hb_compExprAsLongNum( pArg ); while( --usCount ) { pArg = pArg->pNext; @@ -1830,10 +1818,8 @@ static HB_EXPR_FUNC( hb_compExprUseFunCall ) lResult |= hb_compExprAsLongNum( pArg ); } } - else if( strcmp( "XOR", pName->value.asSymbol + 6 ) == 0 ) + else if( pSelf->value.asFunCall.funcid == HB_F_BITXOR ) { - fOptimize = HB_TRUE; - lResult = hb_compExprAsLongNum( pArg ); while( --usCount ) { pArg = pArg->pNext; @@ -1845,82 +1831,71 @@ static HB_EXPR_FUNC( hb_compExprUseFunCall ) lResult ^= hb_compExprAsLongNum( pArg ); } } - else if( strcmp( "TEST", pName->value.asSymbol + 6 ) == 0 ) + else if( pSelf->value.asFunCall.funcid == HB_F_BITSET ) { HB_MAXINT lBit = hb_compExprAsLongNum( pArg->pNext ); - lResult = ( hb_compExprAsLongNum( pArg ) & - ( ( HB_MAXINT ) 1 << lBit ) ) != 0; - fOptimize = fBool = HB_TRUE; + lResult |= ( HB_MAXINT ) 1 << lBit; } - else if( strcmp( "SET", pName->value.asSymbol + 6 ) == 0 ) + else if( pSelf->value.asFunCall.funcid == HB_F_BITRESET ) { HB_MAXINT lBit = hb_compExprAsLongNum( pArg->pNext ); - lResult = hb_compExprAsLongNum( pArg ) | - ( ( HB_MAXINT ) 1 << lBit ); - fOptimize = HB_TRUE; + lResult &= ~( ( HB_MAXINT ) 1 << lBit ); } - else if( strcmp( "RESET", pName->value.asSymbol + 6 ) == 0 ) - { - HB_MAXINT lBit = hb_compExprAsLongNum( pArg->pNext ); - lResult = hb_compExprAsLongNum( pArg ) & - ( ~ ( ( HB_MAXINT ) 1 << lBit ) ); - fOptimize = HB_TRUE; - } - else if( strcmp( "SHIFT", pName->value.asSymbol + 6 ) == 0 ) + else /* if( pSelf->value.asFunCall.funcid == HB_F_BITSHIFT ) */ { HB_MAXINT lBits = hb_compExprAsLongNum( pArg->pNext ); - lResult = hb_compExprAsLongNum( pArg ); if( lBits < 0 ) lResult >>= -lBits; else lResult <<= lBits; - fOptimize = HB_TRUE; } + if( fOptimize ) + hb_compExprReduceBitFunc( pSelf, lResult, HB_FALSE, HB_COMP_PARAM ); } - } - else if( strcmp( "NOT", pName->value.asSymbol + 6 ) == 0 ) - { - lResult = ~hb_compExprAsLongNum( pArg ); - fOptimize = HB_TRUE; - } - if( fOptimize ) - hb_compExprReduceBitFunc( pSelf, lResult, fBool, HB_COMP_PARAM ); - } -#ifndef HB_MACRO_SUPPORT - else if( strncmp( "HB_I18N_", pName->value.asSymbol, 8 ) == 0 ) - { - HB_EXPR_PTR pArg = pParms->value.asList.pExprList, pCount = NULL; - HB_BOOL fStrict, fNoop, fPlural, fI18nFunc; - HB_ULONG ulPos = 8; + break; + case HB_F_BITTEST: + if( usCount >= 2 && + pParms->value.asList.pExprList->ExprType == HB_ET_NUMERIC && + pParms->value.asList.pExprList->pNext->ExprType == HB_ET_NUMERIC ) + { + HB_EXPR_PTR pArg = pParms->value.asList.pExprList; + HB_MAXINT lBit = hb_compExprAsLongNum( pArg->pNext ); + HB_MAXINT lResult = ( hb_compExprAsLongNum( pArg ) & + ( ( HB_MAXINT ) 1 << lBit ) ) != 0; + hb_compExprReduceBitFunc( pSelf, lResult, HB_TRUE, HB_COMP_PARAM ); + } + break; + case HB_F_BITNOT: + if( usCount && pParms->value.asList.pExprList->ExprType == HB_ET_NUMERIC ) + { + HB_MAXINT lResult = ~hb_compExprAsLongNum( pParms->value.asList.pExprList ); + hb_compExprReduceBitFunc( pSelf, lResult, HB_FALSE, HB_COMP_PARAM ); + } + break; - fStrict = fNoop = fPlural = fI18nFunc = HB_FALSE; - if( pName->value.asSymbol[ ulPos ] == 'N' ) - { - fPlural = HB_TRUE; - ulPos++; - } - if( strncmp( "GETTEXT", &pName->value.asSymbol[ ulPos ], 7 ) == 0 ) - { - ulPos += 7; - if( strncmp( "_STRICT", &pName->value.asSymbol[ ulPos ], 7 ) == 0 ) - { - ulPos += 7; - fStrict = HB_TRUE; - } - else if( strncmp( "_NOOP", &pName->value.asSymbol[ ulPos ], 5 ) == 0 ) - { - ulPos += 5; - fNoop = HB_TRUE; - } - if( !pName->value.asSymbol[ ulPos ] || pName->value.asSymbol[ ulPos ] == '_' ) - fI18nFunc = HB_TRUE; - } - if( fI18nFunc ) +#ifndef HB_MACRO_SUPPORT + case HB_F_I18N_GETTEXT: + case HB_F_I18N_GETTEXT_NOOP: + case HB_F_I18N_GETTEXT_STRICT: + case HB_F_I18N_NGETTEXT: + case HB_F_I18N_NGETTEXT_NOOP: + case HB_F_I18N_NGETTEXT_STRICT: { + HB_EXPR_PTR pArg = pParms->value.asList.pExprList, + pCount = NULL, pBadParam = NULL; int iWarning = 0; - HB_EXPR_PTR pBadParam = NULL; const char * szExpect = NULL; const char * szContext = NULL; + HB_BOOL fStrict, fNoop, fPlural; + HB_FUNC_ID funcID = pSelf->value.asFunCall.funcid; + + fStrict = funcID == HB_F_I18N_GETTEXT_STRICT || + funcID == HB_F_I18N_GETTEXT_STRICT; + fNoop = funcID == HB_F_I18N_GETTEXT_NOOP || + funcID == HB_F_I18N_GETTEXT_NOOP; + fPlural = funcID == HB_F_I18N_NGETTEXT || + funcID == HB_F_I18N_NGETTEXT_NOOP || + funcID == HB_F_I18N_NGETTEXT_STRICT; if( fPlural && usCount ) { @@ -2068,9 +2043,14 @@ static HB_EXPR_FUNC( hb_compExprUseFunCall ) /* free pArg expression body but without freeing its subexpressions */ HB_COMP_EXPR_CLEAR( pArg ); } + + break; } - } #endif + default: + /* to pacify enum warning */ + break; + } } } break; diff --git a/harbour/src/common/Makefile b/harbour/src/common/Makefile index 1ad35c74c4..186c1b6486 100644 --- a/harbour/src/common/Makefile +++ b/harbour/src/common/Makefile @@ -7,6 +7,7 @@ ROOT := ../../ C_SOURCES := \ expropt1.c \ expropt2.c \ + funcid.c \ hbffind.c \ hbfopen.c \ hbfsapi.c \ diff --git a/harbour/src/common/funcid.c b/harbour/src/common/funcid.c new file mode 100644 index 0000000000..d6831ad11e --- /dev/null +++ b/harbour/src/common/funcid.c @@ -0,0 +1,151 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * get function identifier + * + * Copyright 2010 Przemyslaw Czerpak + * www - http://www.harbour-project.org + * + * 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 software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). + * + * 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. + * + */ + +#include "hbcomp.h" + +typedef struct +{ + const char * szFuncName; + int iMinLen; + HB_FUNC_ID funcID; +} _HB_FUNCID; + +/* NOTE: THIS TABLE MUST BE SORTED ALPHABETICALLY + */ +static _HB_FUNCID s_funcId[] = +{ + { "ASC", 0, HB_F_ASC }, + { "AT", 0, HB_F_AT }, + { "CHR", 0, HB_F_CHR }, + { "CTOD", 0, HB_F_CTOD }, + { "DTOS", 0, HB_F_DTOS }, + { "EMPTY", 4, HB_F_EMPTY }, + { "EVAL", 0, HB_F_EVAL }, + { "HB_ARRAYTOPARAMS", 0, HB_F_ARRAYTOPARAMS }, + { "HB_BITAND", 0, HB_F_BITAND }, + { "HB_BITNOT", 0, HB_F_BITNOT }, + { "HB_BITOR", 0, HB_F_BITOR }, + { "HB_BITRESET", 0, HB_F_BITRESET }, + { "HB_BITSET", 0, HB_F_BITSET }, + { "HB_BITSHIFT", 0, HB_F_BITSHIFT }, + { "HB_BITTEST", 0, HB_F_BITTEST }, + { "HB_BITXOR", 0, HB_F_BITXOR }, + { "HB_I18N_GETTEXT", 0, HB_F_I18N_GETTEXT }, + { "HB_I18N_GETTEXT_NOOP", 0, HB_F_I18N_GETTEXT_NOOP }, + { "HB_I18N_GETTEXT_STRICT", 0, HB_F_I18N_GETTEXT_STRICT }, + { "HB_I18N_NGETTEXT", 0, HB_F_I18N_NGETTEXT }, + { "HB_I18N_NGETTEXT_NOOP", 0, HB_F_I18N_NGETTEXT_NOOP }, + { "HB_I18N_NGETTEXT_STRICT", 0, HB_F_I18N_NGETTEXT_STRICT }, + { "HB_STOD", 0, HB_F_STOD }, + { "HB_STOT", 0, HB_F_STOT }, + { "INT", 0, HB_F_INT }, + { "LEN", 0, HB_F_LEN }, + { "MAX", 0, HB_F_MAX }, + { "MIN", 0, HB_F_MIN }, + { "STOD", 0, HB_F_STOD }, + { "UPPER", 4, HB_F_UPPER }, + { "_GET_", 0, HB_F__GET_ } +}; + +HB_FUNC_ID hb_compGetFuncID( const char * szFuncName ) +{ + unsigned int uiFirst = 0, uiLast = HB_SIZEOFARRAY( s_funcId ) - 1, uiMiddle; + int i; + + do + { + uiMiddle = ( uiFirst + uiLast ) >> 1; + i = strcmp( szFuncName, s_funcId[ uiMiddle ].szFuncName ); + if( i <= 0 ) + uiLast = uiMiddle; + else + uiFirst = uiMiddle + 1; + } + while( uiFirst < uiLast ); + + if( uiFirst != uiMiddle ) + i = strcmp( szFuncName, s_funcId[ uiFirst ].szFuncName ); + + if( i == 0 ) + return s_funcId[ uiFirst ].funcID; + + if( i > 0 && uiFirst ) + uiFirst--; + + if( s_funcId[ uiFirst ].iMinLen ) + { + int iLen = ( int ) strlen( szFuncName ); + + if( iLen >= s_funcId[ uiFirst ].iMinLen && + strncmp( szFuncName, s_funcId[ uiMiddle ].szFuncName, iLen ) == 0 ) + return s_funcId[ uiFirst ].funcID; + } + + /* hack for HB_I18N_GETTEXT_[NOOP_|STRICT_]* functions */ + if( strncmp( szFuncName, "HB_I18N_", 8 ) == 0 ) + { + szFuncName += 8; + i = *szFuncName == 'N' ? 1 : 0; + szFuncName += i; + if( strncmp( szFuncName, "GETTEXT_", 8 ) == 0 ) + { + if( strncmp( szFuncName, "STRICT_", 7 ) == 0 ) + return i == 0 ? HB_F_I18N_GETTEXT_STRICT : HB_F_I18N_NGETTEXT_STRICT; + else if( strncmp( szFuncName, "NOOP_", 5 ) == 0 ) + return i == 0 ? HB_F_I18N_GETTEXT_NOOP : HB_F_I18N_NGETTEXT_NOOP; + else + return i == 0 ? HB_F_I18N_GETTEXT : HB_F_I18N_NGETTEXT; + } + } + + return HB_F_UDF; +} diff --git a/harbour/src/common/reserved.c b/harbour/src/common/reserved.c index 023a43400f..b90aa7db3b 100644 --- a/harbour/src/common/reserved.c +++ b/harbour/src/common/reserved.c @@ -124,13 +124,13 @@ static const char * s_szReservedFun[] = { "YEAR" }; -#define RESERVED_FUNCTIONS ( sizeof( s_szReservedFun ) / sizeof( char * ) ) #endif const char * hb_compReservedName( const char * szName ) { #if !defined( HB_RESERVED_OFF ) - unsigned int uiFirst = 0, uiLast = RESERVED_FUNCTIONS - 1, uiMiddle; + unsigned int uiFirst = 0, uiLast = HB_SIZEOFARRAY( s_szReservedFun ) - 1, + uiMiddle; int iLen = ( int ) strlen( szName ), iCmp; /* Respect 4 or more letters shortcuts @@ -154,7 +154,7 @@ const char * hb_compReservedName( const char * szName ) iCmp = strncmp( szName, s_szReservedFun[ uiFirst ], iLen ); if( iCmp == 0 ) - return ( char * ) s_szReservedFun[ uiFirst ]; + return s_szReservedFun[ uiFirst ]; #else HB_SYMBOL_UNUSED( szName ); #endif diff --git a/harbour/src/vm/eval.c b/harbour/src/vm/eval.c index e5a17e6e88..7d79c813da 100644 --- a/harbour/src/vm/eval.c +++ b/harbour/src/vm/eval.c @@ -475,6 +475,13 @@ HB_FUNC( HB_EXECFROMARRAY ) if( pExecSym ) { + pFunc = hb_stackBaseItem(); + pItem = hb_stackItem( pFunc->item.asSymbol.stackstate->lBaseItem ); + pFunc->item.asSymbol.stackstate->uiClass = + pItem->item.asSymbol.stackstate->uiClass; + pFunc->item.asSymbol.stackstate->uiMethod = + pItem->item.asSymbol.stackstate->uiMethod; + iPCount = 0; hb_vmPushSymbol( pExecSym ); if( pSelf ) diff --git a/harbour/src/vm/macro.c b/harbour/src/vm/macro.c index c584916b19..9d55082799 100644 --- a/harbour/src/vm/macro.c +++ b/harbour/src/vm/macro.c @@ -1532,16 +1532,11 @@ void hb_macroGenPushFunSym( const char * szFunName, HB_COMP_DECL ) szFunction = hb_compReservedName( szFunName ); if( szFunction ) - { - /* Abbreviated function name was used - change it for whole name - */ - hb_macroGenPushSymbol( szFunction, HB_TRUE, HB_COMP_PARAM ); - } + /* if abbreviated function name was used - change it for whole name */ + szFunName = szFunction; else - { HB_MACRO_DATA->status |= HB_MACRO_UDF; /* this is used in hb_macroGetType */ - hb_macroGenPushSymbol( szFunName, HB_TRUE, HB_COMP_PARAM ); - } + hb_macroGenPushSymbol( szFunName, HB_TRUE, HB_COMP_PARAM ); } void hb_macroGenPushFunCall( const char * szFunName, HB_COMP_DECL )