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:
Mindaugas Kavaliauskas
2013-04-19 16:56:30 +03:00
parent 9da92928eb
commit ed6250363e
4 changed files with 102 additions and 41 deletions

View File

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

View File

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

View File

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

View File

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