2013-04-19 16:55 UTC+0300 Mindaugas Kavaliauskas (dbtopas/at/dbtopas.lt)
* harbour/contrib/rddads/adsx.c
! fixed adsSeek() if seek string length is less than index key length
* harbour/src/compiler/hbopt.c
! improved BEGIN/END SEQUENCE support in code trace optimizer. Problem
of false positive warning 'Variable is assigned but not used' is solved
in cases like:
FUNC TEST()
LOCAL n := 1
BEGIN SEQUENCE
IF n == 1
n := 2
BREAK
ENDIF
n := 3
END SEQUENCE
RETURN n
; TODO: test for more complicated cases like nested BEGIN/END SEQUENCE
* harbour/src/rdd/dbf1.c
* added :GetValue() GPF protection if area is "half opened" (ex.,
enumerating field values in error handler on area open failure).
More general solution for "half opened" workareas is welcome
This commit is contained in:
@@ -10,6 +10,31 @@
|
||||
* Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment
|
||||
*/
|
||||
|
||||
2013-04-19 16:55 UTC+0300 Mindaugas Kavaliauskas (dbtopas/at/dbtopas.lt)
|
||||
* harbour/contrib/rddads/adsx.c
|
||||
! fixed adsSeek() if seek string length is less than index key length
|
||||
|
||||
* harbour/src/compiler/hbopt.c
|
||||
! improved BEGIN/END SEQUENCE support in code trace optimizer. Problem
|
||||
of false positive warning 'Variable is assigned but not used' is solved
|
||||
in cases like:
|
||||
FUNC TEST()
|
||||
LOCAL n := 1
|
||||
BEGIN SEQUENCE
|
||||
IF n == 1
|
||||
n := 2
|
||||
BREAK
|
||||
ENDIF
|
||||
n := 3
|
||||
END SEQUENCE
|
||||
RETURN n
|
||||
; TODO: test for more complicated cases like nested BEGIN/END SEQUENCE
|
||||
|
||||
* harbour/src/rdd/dbf1.c
|
||||
* added :GetValue() GPF protection if area is "half opened" (ex.,
|
||||
enumerating field values in error handler on area open failure).
|
||||
More general solution for "half opened" workareas is welcome
|
||||
|
||||
2013-04-19 16:35 UTC+0300 Mindaugas Kavaliauskas (dbtopas/at/dbtopas.lt)
|
||||
* contrib/hbct/token1.c
|
||||
* contrib/hbpgsql/rddcopy.c
|
||||
|
||||
@@ -341,7 +341,7 @@ static void mixQSort( PMIXKEY * pKeys, HB_ULONG left, HB_ULONG right, HB_USHORT
|
||||
}
|
||||
|
||||
|
||||
static PMIXKEY mixFindKey( PMIXTAG pTag, PMIXKEY pKey, HB_ULONG * ulKeyPos )
|
||||
static PMIXKEY mixFindKeyLen( PMIXTAG pTag, PMIXKEY pKey, HB_USHORT uiLen, HB_ULONG * ulKeyPos )
|
||||
{
|
||||
HB_ULONG l, r;
|
||||
int i = 1;
|
||||
@@ -358,7 +358,7 @@ static PMIXKEY mixFindKey( PMIXTAG pTag, PMIXKEY pKey, HB_ULONG * ulKeyPos )
|
||||
|
||||
while( l < r )
|
||||
{
|
||||
i = mixQSortCompare( pTag->pKeys[ ( l + r ) / 2 ], pKey, pTag->uiLen, pTag->pCodepage );
|
||||
i = mixQSortCompare( pTag->pKeys[ ( l + r ) / 2 ], pKey, uiLen, pTag->pCodepage );
|
||||
|
||||
if( i < 0 )
|
||||
l = ( l + r ) / 2 + 1;
|
||||
@@ -370,7 +370,7 @@ static PMIXKEY mixFindKey( PMIXTAG pTag, PMIXKEY pKey, HB_ULONG * ulKeyPos )
|
||||
|
||||
if( i )
|
||||
{
|
||||
i = mixQSortCompare( pTag->pKeys[ l ], pKey, pTag->uiLen, pTag->pCodepage );
|
||||
i = mixQSortCompare( pTag->pKeys[ l ], pKey, uiLen, pTag->pCodepage );
|
||||
if( i < 0 )
|
||||
l++;
|
||||
}
|
||||
@@ -382,9 +382,15 @@ static PMIXKEY mixFindKey( PMIXTAG pTag, PMIXKEY pKey, HB_ULONG * ulKeyPos )
|
||||
}
|
||||
|
||||
|
||||
static int mixCompareKey( PMIXTAG pTag, HB_ULONG ulKeyPos, PMIXKEY pKey )
|
||||
static PMIXKEY mixFindKey( PMIXTAG pTag, PMIXKEY pKey, HB_ULONG * ulKeyPos )
|
||||
{
|
||||
return mixQSortCompare( pTag->pKeys[ ulKeyPos ], pKey, pTag->uiLen, pTag->pCodepage );
|
||||
return mixFindKeyLen( pTag, pKey, pTag->uiLen, ulKeyPos );
|
||||
}
|
||||
|
||||
|
||||
static int mixCompareKey( PMIXTAG pTag, HB_ULONG ulKeyPos, PMIXKEY pKey, HB_USHORT uiLen )
|
||||
{
|
||||
return mixQSortCompare( pTag->pKeys[ ulKeyPos ], pKey, uiLen, pTag->pCodepage );
|
||||
}
|
||||
|
||||
|
||||
@@ -661,7 +667,7 @@ static void mixUpdateDestroy( ADSXAREAP pArea, PMIXUPDATE pUpdate, int fUpdate )
|
||||
PMIXKEY pKey = mixKeyEval( pTag, pArea );
|
||||
if( bFor )
|
||||
{
|
||||
if( mixCompareKey( pTag, pUpdate[ iTag ], pKey ) != 0 )
|
||||
if( mixCompareKey( pTag, pUpdate[ iTag ], pKey, pTag->uiLen ) != 0 )
|
||||
{
|
||||
HB_ULONG ulKeyPos;
|
||||
mixKeyFree( pTag->pKeys[ pUpdate[ iTag ] ] );
|
||||
@@ -767,6 +773,7 @@ static HB_ERRCODE adsxGoTop( ADSXAREAP pArea )
|
||||
static HB_ERRCODE adsxSeek( ADSXAREAP pArea, HB_BOOL bSoftSeek, PHB_ITEM pKey, HB_BOOL bFindLast )
|
||||
{
|
||||
PMIXKEY pMixKey;
|
||||
HB_USHORT uiLen;
|
||||
HB_ULONG ulKeyPos, ulRecNo;
|
||||
HB_ERRCODE errCode;
|
||||
HB_BOOL fFound = HB_FALSE;
|
||||
@@ -775,19 +782,26 @@ static HB_ERRCODE adsxSeek( ADSXAREAP pArea, HB_BOOL bSoftSeek, PHB_ITEM pKey, H
|
||||
return SUPER_SEEK( ( AREAP ) pArea, bSoftSeek, pKey, bFindLast );
|
||||
|
||||
/* TODO: pKey type validation, EG_DATATYPE runtime error */
|
||||
pMixKey = mixKeyNew( pKey, bFindLast ? ( HB_ULONG ) ( -1 ) : 0, pArea->pTagCurrent->bType,
|
||||
pArea->pTagCurrent->uiLen );
|
||||
uiLen = pArea->pTagCurrent->uiLen;
|
||||
pMixKey = mixKeyNew( pKey, bFindLast ? ( HB_ULONG ) ( -1 ) : 0, pArea->pTagCurrent->bType, uiLen );
|
||||
|
||||
if( pArea->pTagCurrent->bType == 'C' )
|
||||
{
|
||||
HB_SIZE ul = hb_itemGetCLen( pKey );
|
||||
if( ul < ( HB_SIZE ) uiLen )
|
||||
uiLen = ( HB_USHORT ) ul;
|
||||
}
|
||||
|
||||
/* reset any pending relations - I hope ACE make the same and the problem
|
||||
reported in GOTO() does not exist here */
|
||||
SELF_RESETREL( &pArea->adsarea );
|
||||
|
||||
mixFindKey( pArea->pTagCurrent, pMixKey, &ulKeyPos );
|
||||
mixFindKeyLen( pArea->pTagCurrent, pMixKey, uiLen, &ulKeyPos );
|
||||
|
||||
ulRecNo = 0;
|
||||
if( bFindLast )
|
||||
{
|
||||
if( ulKeyPos > 0 && mixCompareKey( pArea->pTagCurrent, ulKeyPos - 1, pMixKey ) == -1 )
|
||||
if( ulKeyPos > 0 && mixCompareKey( pArea->pTagCurrent, ulKeyPos - 1, pMixKey, uiLen ) == -1 )
|
||||
{
|
||||
ulRecNo = pArea->pTagCurrent->pKeys[ ulKeyPos - 1 ]->rec;
|
||||
fFound = HB_TRUE;
|
||||
@@ -803,7 +817,7 @@ static HB_ERRCODE adsxSeek( ADSXAREAP pArea, HB_BOOL bSoftSeek, PHB_ITEM pKey, H
|
||||
if( ulKeyPos < pArea->pTagCurrent->ulRecCount )
|
||||
{
|
||||
ulRecNo = pArea->pTagCurrent->pKeys[ ulKeyPos ]->rec;
|
||||
fFound = mixCompareKey( pArea->pTagCurrent, ulKeyPos, pMixKey ) == 1;
|
||||
fFound = mixCompareKey( pArea->pTagCurrent, ulKeyPos, pMixKey, uiLen ) == 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -965,20 +965,8 @@ static HB_BOOL hb_compIsUncondJump( HB_BYTE bPCode )
|
||||
{
|
||||
return bPCode == HB_P_JUMPNEAR ||
|
||||
bPCode == HB_P_JUMP ||
|
||||
bPCode == HB_P_JUMPFAR;
|
||||
/* || bPCode == HB_P_SEQEND;
|
||||
BEGIN SEQUENCE/END SEQUENCE logic could not be processed using conditional/unconditional
|
||||
jumps. I set HB_P_SEQEND as conditional jump though this PCode instruction is processed
|
||||
as unconditional jump by Harbour VM. This hack solves 'Variable is assigned but not used'
|
||||
warning in code:
|
||||
BEGIN SEQUENCE
|
||||
nI := 1
|
||||
Break( NIL )
|
||||
RECOVER
|
||||
? nI
|
||||
END SEQUENCE
|
||||
[Mindaugas]
|
||||
*/
|
||||
bPCode == HB_P_JUMPFAR ||
|
||||
bPCode == HB_P_SEQEND;
|
||||
}
|
||||
|
||||
#if 0
|
||||
@@ -1256,7 +1244,7 @@ static void hb_compPCodeEnumSelfifyLocal( PHB_HFUNC pFunc, HB_SHORT isLocal )
|
||||
}
|
||||
|
||||
|
||||
static int hb_compPCodeTraceAssignedUnused( PHB_HFUNC pFunc, HB_SIZE nPos, HB_BYTE * pMap, HB_SHORT isLocal )
|
||||
static int hb_compPCodeTraceAssignedUnused( PHB_HFUNC pFunc, HB_SIZE nPos, HB_BYTE * pMap, HB_SHORT isLocal, HB_BOOL fCanBreak )
|
||||
{
|
||||
for( ;; )
|
||||
{
|
||||
@@ -1265,22 +1253,56 @@ static int hb_compPCodeTraceAssignedUnused( PHB_HFUNC pFunc, HB_SIZE nPos, HB_BY
|
||||
|
||||
pMap[ nPos ] = 1;
|
||||
|
||||
if( pFunc->pCode[ nPos ] == HB_P_POPLOCAL ||
|
||||
pFunc->pCode[ nPos ] == HB_P_POPLOCALNEAR ||
|
||||
pFunc->pCode[ nPos ] == HB_P_PUSHLOCAL ||
|
||||
pFunc->pCode[ nPos ] == HB_P_PUSHLOCALNEAR ||
|
||||
pFunc->pCode[ nPos ] == HB_P_PUSHLOCALREF ||
|
||||
pFunc->pCode[ nPos ] == HB_P_LOCALINCPUSH ||
|
||||
pFunc->pCode[ nPos ] == HB_P_LOCALDEC ||
|
||||
pFunc->pCode[ nPos ] == HB_P_LOCALINC ||
|
||||
pFunc->pCode[ nPos ] == HB_P_LOCALADDINT ||
|
||||
pFunc->pCode[ nPos ] == HB_P_LOCALNEARADDINT )
|
||||
|
||||
if( pFunc->pCode[ nPos ] == HB_P_FUNCTION ||
|
||||
pFunc->pCode[ nPos ] == HB_P_FUNCTIONSHORT ||
|
||||
pFunc->pCode[ nPos ] == HB_P_DO ||
|
||||
pFunc->pCode[ nPos ] == HB_P_DOSHORT ||
|
||||
pFunc->pCode[ nPos ] == HB_P_SEND ||
|
||||
pFunc->pCode[ nPos ] == HB_P_SENDSHORT ||
|
||||
pFunc->pCode[ nPos ] == HB_P_MACRODO ||
|
||||
pFunc->pCode[ nPos ] == HB_P_MACROFUNC ||
|
||||
pFunc->pCode[ nPos ] == HB_P_MACROSEND )
|
||||
{
|
||||
fCanBreak = HB_TRUE;
|
||||
}
|
||||
else if( pFunc->pCode[ nPos ] == HB_P_POPLOCAL ||
|
||||
pFunc->pCode[ nPos ] == HB_P_POPLOCALNEAR ||
|
||||
pFunc->pCode[ nPos ] == HB_P_PUSHLOCAL ||
|
||||
pFunc->pCode[ nPos ] == HB_P_PUSHLOCALNEAR ||
|
||||
pFunc->pCode[ nPos ] == HB_P_PUSHLOCALREF ||
|
||||
pFunc->pCode[ nPos ] == HB_P_LOCALINCPUSH ||
|
||||
pFunc->pCode[ nPos ] == HB_P_LOCALDEC ||
|
||||
pFunc->pCode[ nPos ] == HB_P_LOCALINC ||
|
||||
pFunc->pCode[ nPos ] == HB_P_LOCALADDINT ||
|
||||
pFunc->pCode[ nPos ] == HB_P_LOCALNEARADDINT )
|
||||
|
||||
{
|
||||
if( hb_compLocalGetNumber( pFunc->pCode + nPos ) == isLocal )
|
||||
{
|
||||
if( pFunc->pCode[ nPos ] == HB_P_POPLOCAL ||
|
||||
pFunc->pCode[ nPos ] == HB_P_POPLOCALNEAR )
|
||||
return 0;
|
||||
{
|
||||
if( fCanBreak )
|
||||
{
|
||||
nPos += hb_compPCodeSize( pFunc, nPos );
|
||||
while( pFunc->pCode[ nPos ] != HB_P_ENDPROC && pFunc->pCode[ nPos ] != HB_P_ENDBLOCK &&
|
||||
pFunc->pCode[ nPos ] != HB_P_SEQBEGIN && pFunc->pCode[ nPos ] != HB_P_SEQEND )
|
||||
{
|
||||
nPos += hb_compPCodeSize( pFunc, nPos );
|
||||
}
|
||||
if( pFunc->pCode[ nPos ] == HB_P_SEQEND )
|
||||
{
|
||||
/* Process RECOVER */
|
||||
fCanBreak = HB_FALSE;
|
||||
nPos += hb_compPCodeSize( pFunc, nPos );
|
||||
continue;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
@@ -1301,7 +1323,7 @@ static int hb_compPCodeTraceAssignedUnused( PHB_HFUNC pFunc, HB_SIZE nPos, HB_BY
|
||||
continue;
|
||||
}
|
||||
|
||||
if( hb_compPCodeTraceAssignedUnused( pFunc, nPos2, pMap, isLocal ) )
|
||||
if( hb_compPCodeTraceAssignedUnused( pFunc, nPos2, pMap, isLocal, fCanBreak ) )
|
||||
return 1;
|
||||
}
|
||||
else if( pFunc->pCode[ nPos ] == HB_P_SWITCH ) /* Switch is multiplace jump */
|
||||
@@ -1311,7 +1333,7 @@ static int hb_compPCodeTraceAssignedUnused( PHB_HFUNC pFunc, HB_SIZE nPos, HB_BY
|
||||
nPos += 3;
|
||||
for( us = 0; us < usCount; us++ )
|
||||
{
|
||||
if( hb_compPCodeTraceAssignedUnused( pFunc, nPos, pMap, isLocal ) )
|
||||
if( hb_compPCodeTraceAssignedUnused( pFunc, nPos, pMap, isLocal, fCanBreak ) )
|
||||
return 1;
|
||||
|
||||
nPos += hb_compPCodeSize( pFunc, nPos );
|
||||
@@ -1423,7 +1445,7 @@ static void hb_compPCodeEnumAssignedUnused( HB_COMP_DECL, PHB_HFUNC pFunc, PHB_O
|
||||
pMap[ nPos ] = 1;
|
||||
|
||||
if( ! hb_compPCodeTraceAssignedUnused( pFunc, nPos + hb_compPCodeSize( pFunc, nPos ),
|
||||
pMap, isLocal ) )
|
||||
pMap, isLocal, HB_FALSE ) )
|
||||
{
|
||||
char szFun[ 256 ];
|
||||
|
||||
|
||||
@@ -2022,7 +2022,7 @@ static HB_ERRCODE hb_dbfGetValue( DBFAREAP pArea, HB_USHORT uiIndex, PHB_ITEM pI
|
||||
}
|
||||
|
||||
/* Read record */
|
||||
if( ! pArea->fValidBuffer && ! hb_dbfReadRecord( pArea ) )
|
||||
if( ! pArea->pRecord || ! pArea->fValidBuffer && ! hb_dbfReadRecord( pArea ) )
|
||||
return HB_FAILURE;
|
||||
|
||||
if( --uiIndex >= pArea->area.uiFieldCount )
|
||||
|
||||
Reference in New Issue
Block a user