From ea4a76e6147eaf084dc6401067661afb99f73a70 Mon Sep 17 00:00:00 2001 From: Bruno Cantero Date: Wed, 25 Aug 1999 15:39:21 +0000 Subject: [PATCH] ChangeLogTag:19990825-17:22 GMT+1 Bruno Cantero --- harbour/ChangeLog | 9 +++ harbour/source/rdd/dbcmd.c | 81 ++++++++++++++------- harbour/source/rdd/dbf1.c | 142 +++++++++++++++++++++++++++---------- harbour/source/vm/hvm.c | 95 +++++++++++++++++++++---- 4 files changed, 251 insertions(+), 76 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index cb1ed0c011..15e9557c94 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,12 @@ +19990825-17:22 GMT+1 Bruno Cantero + * source/vm/hvm.c + + Added support for FIELD symbols + * source/rdd/dbcmd.c + + Open function improved + + Added support for FIELD symbols + * source/rdd/dbf1.c + + PutValue function improved + 19990825-13:30 GMT+2 Ryszard Glab *source/vm/hvm.c diff --git a/harbour/source/rdd/dbcmd.c b/harbour/source/rdd/dbcmd.c index 5584482af9..321d6372eb 100644 --- a/harbour/source/rdd/dbcmd.c +++ b/harbour/source/rdd/dbcmd.c @@ -129,10 +129,7 @@ static ERRCODE AddField( AREAP pArea, LPDBFIELDINFO pFieldInfo ) pField = pArea->lpFields + pArea->uiFieldCount; if( pArea->uiFieldCount > 0 ) ( ( LPFIELD ) ( pField - 1 ) )->lpfNext = pField; - pField->sym = ( void * ) hb_xgrab( HARBOUR_MAX_RDD_FIELDNAME_LENGTH + 1 ); - memset( pField->sym, 0, HARBOUR_MAX_RDD_FIELDNAME_LENGTH + 1 ); - strncpy( ( char * ) pField->sym, ( char * ) pFieldInfo->atomName, - HARBOUR_MAX_RDD_FIELDNAME_LENGTH ); + pField->sym = ( void * ) hb_dynsymGet( ( char * ) pFieldInfo->atomName ); pField->uiType = pFieldInfo->uiType; pField->uiTypeExtended = pFieldInfo->typeExtended; pField->uiLen = pFieldInfo->uiLen; @@ -216,8 +213,7 @@ static ERRCODE FieldInfo( AREAP pArea, USHORT uiIndex, USHORT uiType, PHB_ITEM p switch( uiType ) { case DBS_NAME: - hb_itemPutCL( pItem, ( char * ) pField->sym, - HARBOUR_MAX_RDD_FIELDNAME_LENGTH ); + hb_itemPutC( pItem, ( ( PHB_DYNS ) pField->sym )->pSymbol->szName ); return SUCCESS; case DBS_TYPE: @@ -251,7 +247,7 @@ static ERRCODE FieldName( AREAP pArea, USHORT uiIndex, void * szName ) } if( pField ) { - strncpy( ( char * ) szName, ( char * ) pField->sym, + strncpy( ( char * ) szName, ( ( PHB_DYNS ) pField->sym )->pSymbol->szName, HARBOUR_MAX_RDD_FIELDNAME_LENGTH ); return SUCCESS; } @@ -294,14 +290,14 @@ static ERRCODE NewArea( AREAP pArea ) static ERRCODE Open( AREAP pArea, LPDBOPENINFO pOpenInfo ) { - pArea->atomAlias = hb_dynsymFind( ( char * ) pOpenInfo->atomAlias ); - if( pArea->atomAlias && ( ( PHB_DYNS ) pArea->atomAlias )->hArea ) + pArea->atomAlias = hb_dynsymGet( ( char * ) pOpenInfo->atomAlias ); + if( ( ( PHB_DYNS ) pArea->atomAlias )->hArea ) { hb_errRT_DBCMD( EG_DUPALIAS, 1011, 0, ( char * ) pOpenInfo->atomAlias ); return FAILURE; } - pArea->atomAlias = hb_dynsymGet( ( char * ) pOpenInfo->atomAlias ); - ( ( PHB_DYNS ) pArea->atomAlias )->hArea = pOpenInfo->uiArea; + else + ( ( PHB_DYNS ) pArea->atomAlias )->hArea = pOpenInfo->uiArea; return SUCCESS; } @@ -309,19 +305,9 @@ static ERRCODE Open( AREAP pArea, LPDBOPENINFO pOpenInfo ) static ERRCODE Release( AREAP pArea ) { LPFILEINFO pFileInfo; - LPFIELD pField; if( pArea->lpFields ) - { - pField = pArea->lpFields; - while( pField ) - { - if( pField->sym ) - hb_xfree( pField->sym ); - pField = pField->lpfNext; - } hb_xfree( pArea->lpFields ); - } while( pArea->lpFileInfo ) { @@ -660,6 +646,52 @@ void hb_rddSelectWorkAreaAlias( char * szName ) hb_xfree( szAlias ); } +void hb_rddGetFieldValue( HB_ITEM_PTR pItem, PHB_SYMB pFieldSymbol ) +{ + LPFIELD pField; + USHORT uiField; + + if( pCurrArea ) + { + uiField = 1; + pField = ( ( AREAP ) pCurrArea->pArea )->lpFields; + while( pField ) + { + if( ( ( PHB_DYNS ) pField->sym )->pSymbol == pFieldSymbol ) + { + SELF_GETVALUE( ( AREAP ) pCurrArea->pArea, uiField, pItem ); + return; + } + pField = pField->lpfNext; + uiField++; + } + } + hb_errRT_BASE( EG_NOVAR, 1003, 0, pFieldSymbol->szName ); +} + +void hb_rddPutFieldValue( HB_ITEM_PTR pItem, PHB_SYMB pFieldSymbol ) +{ + LPFIELD pField; + USHORT uiField; + + if( pCurrArea ) + { + uiField = 1; + pField = ( ( AREAP ) pCurrArea->pArea )->lpFields; + while( pField ) + { + if( ( ( PHB_DYNS ) pField->sym )->pSymbol == pFieldSymbol ) + { + SELF_PUTVALUE( ( AREAP ) pCurrArea->pArea, uiField, pItem ); + return; + } + pField = pField->lpfNext; + uiField++; + } + } + hb_errRT_BASE( EG_NOVAR, 1003, 0, pFieldSymbol->szName ); +} + /* * -- HARBOUR FUNCTIONS -- */ @@ -1048,9 +1080,9 @@ HARBOUR HB_DBSTRUCT( void ) { SELF_FIELDCOUNT( ( AREAP ) pCurrArea->pArea, &uiFields ); pData = hb_itemNew( NULL ); + pItem = hb_itemNew( NULL ); for( uiCount = 1; uiCount <= uiFields; uiCount++ ) { - pItem = hb_itemNew( NULL ); hb_arrayNew( pItem, 4 ); SELF_FIELDINFO( ( AREAP ) pCurrArea->pArea, uiCount, DBS_NAME, pData ); hb_arraySet( pItem, 1, pData ); @@ -1062,6 +1094,7 @@ HARBOUR HB_DBSTRUCT( void ) hb_arraySet( pItem, 4, pData ); hb_arrayAdd( &stack.Return, pItem ); } + hb_itemRelease( pItem ); hb_itemRelease( pData ); } } @@ -1214,7 +1247,7 @@ HARBOUR HB_DBUSEAREA( void ) if( uiSize > sizeof( AREA ) ) /* Size of Area changed */ pCurrArea->pArea = ( AREAP ) hb_xrealloc( pCurrArea->pArea, uiSize ); - pRddNode->uiAreaSize = uiSize; /* Update the size of WorkArea */ + pRddNode->uiAreaSize = uiSize; /* Update the size of WorkArea */ } else { @@ -1364,7 +1397,7 @@ HARBOUR HB_FIELDPOS( void ) pField = ( ( AREAP ) pCurrArea->pArea )->lpFields; while( pField ) { - if( strcmp( szName, ( char * ) pField->sym ) == 0 ) + if( strcmp( szName, ( ( PHB_DYNS ) pField->sym )->pSymbol->szName ) == 0 ) { hb_retni( uiCount + 1 ); return; diff --git a/harbour/source/rdd/dbf1.c b/harbour/source/rdd/dbf1.c index de5b4f26f7..f06f238321 100644 --- a/harbour/source/rdd/dbf1.c +++ b/harbour/source/rdd/dbf1.c @@ -80,6 +80,79 @@ HB_INIT_SYMBOLS_END( dbf1__InitSymbols ) #define LOCK_START 0x40000000L #define LOCK_FILE 0x3FFFFFFFL +static BOOL hb_nltoa( LONG lValue, char * szBuffer, USHORT uiLen ) +{ + LONG lAbsNumber; + int iCount, iPos; + + lAbsNumber = ( lValue > 0 ) ? lValue : - lValue; + iCount = iPos = uiLen; + while( iCount-- > 0 ) + { + szBuffer[ iCount ] = ( '0' + lAbsNumber % 10 ); + lAbsNumber /= 10; + } + + if( lAbsNumber > 0 ) + { + memset( szBuffer, ' ', uiLen ); + return FALSE; + } + + uiLen--; + for( iCount= 0; iCount < uiLen; iCount++ ) + if( szBuffer[ iCount ] == '0' ) + szBuffer[ iCount ] = ' '; + else + break; + + if( lValue < 0 ) + { + if( szBuffer[ 0 ] != ' ' ) + { + memset( szBuffer, ' ', iPos ); + return FALSE; + } + for( iCount = uiLen; iCount >= 0; iCount-- ) + { + if( szBuffer[ iCount ] == ' ' ) + { + szBuffer[ iCount ] = '-'; + break; + } + } + } + return TRUE; +} + +static BOOL hb_ndtoa( double dValue, char * szBuffer, USHORT uiLen, USHORT uiDec ) +{ + double dAbsNumber; + int iCount; + char szEndChar; + + if( uiLen > 19 ) + uiLen = 19; + if( uiDec + 2 > uiLen ) + uiDec = uiLen - 2 ; + if( uiDec > 15 ) + uiDec = 15; + dAbsNumber = ( dValue > 0 ) ? dValue : - dValue; + iCount = uiLen - uiDec - 1; + while( iCount-- > 0 ) + dAbsNumber /= 10; + + if( dAbsNumber > 1 || dValue >= 10000000000000000000.0 ) + { + memset( szBuffer, ' ', uiLen ); + return FALSE; + } + szEndChar = szBuffer[ uiLen ]; + sprintf( szBuffer, "%*.*f", uiLen - uiDec - 1, uiDec, dValue ); + szBuffer[ uiLen ] = szEndChar; + return TRUE; +} + static BOOL hb_rddIsLocked( AREAP pArea, LONG lLockPos ) { LONG lNumLocksPos; @@ -298,7 +371,7 @@ static ERRCODE GetValue( AREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) { LPFIELD pField; USHORT uiCount, uiOffset; - BYTE * szText, * szOldChar, szEndChar; + BYTE * szText, szEndChar; if( uiIndex > pArea->uiFieldCount ) return FAILURE; @@ -323,22 +396,20 @@ static ERRCODE GetValue( AREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) break; case 'N': - szOldChar = szText + pField->uiLen; - szEndChar = * szOldChar; - * szOldChar = 0; + szEndChar = * ( szText + pField->uiLen ); + * ( szText + pField->uiLen ) = 0; if( pField->uiDec ) hb_itemPutND( pItem, atof( ( char * ) szText ) ); else - hb_itemPutNL( pItem, atof( ( char * ) szText ) ); - * szOldChar = szEndChar; + hb_itemPutNL( pItem, atol( ( char * ) szText ) ); + * ( szText + pField->uiLen ) = szEndChar; break; case 'D': - szOldChar = szText + pField->uiLen; - szEndChar = * szOldChar; - * szOldChar = 0; + szEndChar = * ( szText + pField->uiLen ); + * ( szText + pField->uiLen ) = 0; hb_itemPutDS( pItem, ( char * ) szText ); - * szOldChar = szEndChar; + * ( szText + pField->uiLen ) = szEndChar; break; case 'L': @@ -487,7 +558,7 @@ static ERRCODE PutValue( AREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) { LPFIELD pField; USHORT uiCount, uiOffset; - BYTE * szText, * szOldChar, szEndChar; + BYTE * szText, szEndChar; BOOL bError; long lDay, lMonth, lYear; PHB_ITEM pError; @@ -519,42 +590,38 @@ static ERRCODE PutValue( AREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) szText = pArea->lpExtendInfo->bRecord + uiOffset; bError = TRUE; - szOldChar = szText + pField->uiLen; switch( pField->uiType ) { case 'C': if( pItem->type & IT_STRING ) { - szOldChar = szText + pField->uiLen + ( ( USHORT ) pField->uiDec << 8 ); - szEndChar = * szOldChar; - sprintf( ( char * ) szText, "%-*s", pField->uiLen, pItem->item.asString.value ); + uiCount = pItem->item.asString.length; + if( uiCount > pField->uiLen ) + uiCount = pField->uiLen; + memcpy( szText, pItem->item.asString.value, uiCount ); + memset( szText + uiCount, ' ', pField->uiLen - uiCount ); bError = FALSE; } break; case 'N': - if( pItem->type & IT_INTEGER ) + if( pItem->type & IT_NUMERIC ) { if( pField->uiDec ) - sprintf( ( char * ) szText, "%*.*f", pField->uiLen, pField->uiDec, ( double ) pItem->item.asInteger.value ); + bError = !hb_ndtoa( hb_itemGetND( pItem ), ( char * ) szText, + pField->uiLen, pField->uiDec ); else - sprintf( ( char * ) szText, "%*i", pField->uiLen, pItem->item.asInteger.value ); - bError = FALSE; - } - else if( pItem->type & IT_LONG ) - { - if( pField->uiDec ) - sprintf( ( char * ) szText, "%*.*f", pField->uiLen, pField->uiDec, ( double ) pItem->item.asLong.value ); - else - sprintf( ( char * ) szText, "%*ld", pField->uiLen, pItem->item.asLong.value ); - bError = FALSE; - } - else if( pItem->type & IT_DOUBLE ) - { - if( pField->uiDec ) - sprintf( ( char * ) szText, "%*.*f", pField->uiLen, pField->uiDec, pItem->item.asDouble.value ); - else - sprintf( ( char * ) szText, "%*ld", pField->uiLen, ( long ) pItem->item.asDouble.value ); + bError = !hb_nltoa( hb_itemGetNL( pItem ), ( char * ) szText, + pField->uiLen ); + if( bError ) + { + pError = hb_errNew(); + hb_errPutGenCode( pError, EG_DATAWIDTH ); + hb_errPutDescription( pError, hb_langDGetErrorDesc( EG_DATAWIDTH ) ); + hb_errPutSubCode( pError, 1021 ); + SELF_ERROR( pArea, pError ); + hb_errRelease( pError ); + } bError = FALSE; } break; @@ -562,8 +629,10 @@ static ERRCODE PutValue( AREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) case 'D': if( pItem->type & IT_DATE ) { + szEndChar = * ( szText + pField->uiLen ); hb_dateDecode( pItem->item.asDate.value, &lDay, &lMonth, &lYear ); hb_dateStrPut( ( char * ) szText, lDay, lMonth, lYear ); + * ( szText + pField->uiLen ) = szEndChar; bError = FALSE; } break; @@ -579,7 +648,6 @@ static ERRCODE PutValue( AREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) } break; } - * szOldChar = szEndChar; if( bError ) { @@ -788,8 +856,8 @@ static ERRCODE WriteDBHeader( AREAP pArea ) for( uiCount = 0; uiCount < pArea->uiFieldCount; uiCount++ ) { memset( &pDBField, 0, sizeof( DBFFIELD ) ); - strncpy( ( char * ) pDBField.bName, ( const char * ) pField->sym, sizeof( pDBField.bName ) ); - hb_strUpper( ( char * ) pDBField.bName, strlen( ( char * ) pDBField.bName ) ); + strncpy( ( char * ) pDBField.bName, ( ( PHB_DYNS ) pField->sym )->pSymbol->szName, + sizeof( pDBField.bName ) ); pDBField.bType = pField->uiType; switch( pDBField.bType ) { diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index 62a729c072..9a01f0aea4 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -45,6 +45,8 @@ extern void hb_consoleRelease( void ); extern void InitSymbolTable( void ); /* initialization of runtime support symbols */ extern int hb_rddGetCurrentWorkAreaNumber( void ); extern void hb_rddSelectWorkAreaNumber( int iArea ); +extern void hb_rddGetFieldValue( HB_ITEM_PTR pItem, PHB_SYMB pFieldSymbol ); +extern void hb_rddPutFieldValue( HB_ITEM_PTR pItem, PHB_SYMB pFieldSymbol ); typedef struct _SYMBOLS { @@ -1754,8 +1756,44 @@ long hb_vmPopDate( void ) static void hb_vmPopAliasedField( PHB_SYMB pSym ) { - HB_SYMBOL_UNUSED( pSym ); - /* TODO: pop the proper value */ + PHB_ITEM pAlias = stack.pPos - 1; + int iCurrArea = hb_rddGetCurrentWorkAreaNumber(); + + switch( pAlias->type & ~IT_BYREF ) + { + case IT_INTEGER: + /* Alias was used as integer value, for example: 4->field + * or it was saved on the stack using hb_vmAliasPush() + * or was evaluated from an expression, (nWorkArea)->field + */ + hb_rddSelectWorkAreaNumber( pAlias->item.asInteger.value ); + pAlias->type = IT_NIL; + break; + + case IT_SYMBOL: + /* Alias was specified using alias identifier, for example: al->field + */ + hb_rddSelectWorkAreaNumber( pAlias->item.asSymbol.value->pDynSym->hArea ); + pAlias->type = IT_NIL; + break; + + case IT_STRING: + /* Alias was evaluated from an expression, for example: (cVar)->field + */ + /* TODO: synchronize it with RDD API + hb_SelectWorkAreaAlias( pAlias->item.asString.value ); + */ + hb_itemClear( pAlias ); + break; + + default: + hb_itemClear( pAlias ); + hb_errRT_BASE( EG_BADALIAS, 1000, NULL, NULL ); + break; + } + + hb_rddPutFieldValue( stack.pPos - 2, pSym ); + hb_rddSelectWorkAreaNumber( iCurrArea ); hb_stackPop(); /* field */ hb_stackPop(); /* alias */ HB_DEBUG( "hb_vmPopAliasedField\n" ); @@ -1798,8 +1836,7 @@ double hb_vmPopDouble( WORD *pwDec ) static void hb_vmPopField( PHB_SYMB pSym ) { - HB_SYMBOL_UNUSED( pSym ); - /* TODO: pop the proper value */ + hb_rddPutFieldValue( stack.pPos - 1, pSym ); hb_stackPop(); HB_DEBUG( "hb_vmPopField\n" ); } @@ -1921,12 +1958,44 @@ void hb_vmPower( void ) static void hb_vmPushAliasedField( PHB_SYMB pSym ) { - HB_SYMBOL_UNUSED( pSym ); - /* TODO: push the proper value */ - stack.pPos->type = IT_INTEGER; - stack.pPos->item.asInteger.value = 0; - stack.pPos->item.asInteger.length = 10; - hb_stackPush(); + PHB_ITEM pAlias = stack.pPos - 1; + int iCurrArea = hb_rddGetCurrentWorkAreaNumber(); + + switch( pAlias->type & ~IT_BYREF ) + { + case IT_INTEGER: + /* Alias was used as integer value, for example: 4->field + * or it was saved on the stack using hb_vmAliasPush() + * or was evaluated from an expression, (nWorkArea)->field + */ + hb_rddSelectWorkAreaNumber( pAlias->item.asInteger.value ); + pAlias->type = IT_NIL; + break; + + case IT_SYMBOL: + /* Alias was specified using alias identifier, for example: al->field + */ + hb_rddSelectWorkAreaNumber( pAlias->item.asSymbol.value->pDynSym->hArea ); + pAlias->type = IT_NIL; + break; + + case IT_STRING: + /* Alias was evaluated from an expression, for example: (cVar)->field + */ + /* TODO: synchronize it with RDD API + hb_SelectWorkAreaAlias( pAlias->item.asString.value ); + */ + hb_itemClear( pAlias ); + break; + + default: + hb_itemClear( pAlias ); + hb_errRT_BASE( EG_BADALIAS, 1000, NULL, NULL ); + break; + } + + hb_rddGetFieldValue( pAlias, pSym ); + hb_rddSelectWorkAreaNumber( iCurrArea ); HB_DEBUG( "hb_vmPushAliasedField\n" ); } @@ -1940,11 +2009,7 @@ void hb_vmPushLogical( BOOL bValue ) static void hb_vmPushField( PHB_SYMB pSym ) { - HB_SYMBOL_UNUSED( pSym ); - /* TODO: push the proper value */ - stack.pPos->type = IT_INTEGER; - stack.pPos->item.asInteger.value = 0; - stack.pPos->item.asInteger.length = 10; + hb_rddGetFieldValue( stack.pPos, pSym ); hb_stackPush(); HB_DEBUG( "hb_vmPushField\n" ); }