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
This commit is contained in:
Przemyslaw Czerpak
2010-02-27 10:07:03 +00:00
parent f66ee12e71
commit c8aa309764
10 changed files with 400 additions and 212 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -7,6 +7,7 @@ ROOT := ../../
C_SOURCES := \
expropt1.c \
expropt2.c \
funcid.c \
hbffind.c \
hbfopen.c \
hbfsapi.c \

151
harbour/src/common/funcid.c Normal file
View File

@@ -0,0 +1,151 @@
/*
* $Id$
*/
/*
* Harbour Project source code:
* get function identifier
*
* Copyright 2010 Przemyslaw Czerpak <druzus / at / priv.onet.pl>
* 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;
}

View File

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

View File

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

View File

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