From e1f6a0e867a72cc06689c7c43d3cbaacd52e8ed8 Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Tue, 26 Oct 1999 12:24:12 +0000 Subject: [PATCH] 19991026-14:07 GMT+1 --- harbour/ChangeLog | 17 ++++++++ harbour/include/itemapi.h | 2 +- harbour/source/rtl/console.c | 6 ++- harbour/source/rtl/dates.c | 2 + harbour/source/rtl/itemapi.c | 77 +++++++++++++++++++++++------------- harbour/source/rtl/memvars.c | 4 +- harbour/source/rtl/strings.c | 13 ++++-- harbour/source/vm/hvm.c | 3 ++ 8 files changed, 89 insertions(+), 35 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index b52aaed8cb..a1df601df7 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,20 @@ +19991026-14:07 GMT+1 Victor Szel + * include/itemapi.h + source/rtl/itemapi.c + source/rtl/strings.c + source/rtl/console.c + + hb_itemString() made thread safe, while keeping the speed of previous + non-thread safe version for most cases. + * source/rtl/dates.c + + NOTE added about the buffer size requirements of hb_dtoc() + * source/vm/hvm.c + + HB_TRACE() call added to the HB_P_LINE opcode. + * source/rtl/strings.c + ! hb_strncpyUpper() and hb_itemPadConv() HB_TRACE() calls now print the + address of a buffer instead of the (uninitialized) content. + * source/rtl/memvars.c + ! bScope is now showed as a number instead of a char in HB_TRACE() call. + 19991026-12:49 GMT+1 Bruno Cantero * source/rdd/dbf1.c tests/testdbf.prg diff --git a/harbour/include/itemapi.h b/harbour/include/itemapi.h index f5b7ceadcd..454170b6ac 100644 --- a/harbour/include/itemapi.h +++ b/harbour/include/itemapi.h @@ -98,7 +98,7 @@ extern void hb_itemCopy ( PHB_ITEM pDest, PHB_ITEM pSource ); /* copies extern void hb_itemClear ( PHB_ITEM pItem ); extern PHB_ITEM hb_itemUnRef ( PHB_ITEM pItem ); /* de-references passed variable */ extern char * hb_itemStr ( PHB_ITEM pNumber, PHB_ITEM pWidth, PHB_ITEM pDec ); /* convert a number to a string */ -extern char * hb_itemString ( PHB_ITEM pItem, ULONG * ulLen ); /* Convert any scalar to a string */ +extern char * hb_itemString ( PHB_ITEM pItem, ULONG * ulLen, BOOL * bFreeReq ); /* Convert any scalar to a string */ extern PHB_ITEM hb_itemValToStr ( PHB_ITEM pItem ); /* Convert any scalar to a string */ #endif /* HB_ITEMAPI_H_ */ diff --git a/harbour/source/rtl/console.c b/harbour/source/rtl/console.c index b307ae3087..31884c9620 100644 --- a/harbour/source/rtl/console.c +++ b/harbour/source/rtl/console.c @@ -300,15 +300,19 @@ typedef void hb_out_func_typedef( char *, ULONG ); static void hb_out( USHORT uiParam, hb_out_func_typedef * hb_out_func ) { ULONG ulLen; + BOOL bFreeReq; PHB_ITEM pItem; char * pString; HB_TRACE(("hb_out(%hu, %p)", uiParam, hb_out_func)); pItem = hb_param( uiParam, IT_ANY ); - pString = hb_itemString( pItem, &ulLen ); + pString = hb_itemString( pItem, &ulLen, &bFreeReq ); hb_out_func( pString, ulLen ); + + if( bFreeReq ) + hb_xfree( pString ); } /* Output an item to STDOUT */ diff --git a/harbour/source/rtl/dates.c b/harbour/source/rtl/dates.c index 6dd8ca7250..90081fa7bd 100644 --- a/harbour/source/rtl/dates.c +++ b/harbour/source/rtl/dates.c @@ -341,6 +341,8 @@ HARBOUR HB_CTOD( void ) hb_errRT_BASE( EG_ARGCOUNT, 3000, NULL, "CTOD" ); /* NOTE: Clipper catches this at compile time! */ } +/* NOTE: szFormattedDate must be an at least 11 chars wide buffer */ + char * hb_dtoc( const char * szDate, char * szFormattedDate, const char * szDateFormat ) { /* diff --git a/harbour/source/rtl/itemapi.c b/harbour/source/rtl/itemapi.c index e469120c5c..aca24f5c65 100644 --- a/harbour/source/rtl/itemapi.c +++ b/harbour/source/rtl/itemapi.c @@ -94,7 +94,7 @@ BOOL hb_evalNew( PEVALINFO pEvalInfo, PHB_ITEM pItem ) } /* NOTE: CA-Cl*pper is buggy and will not check if more parameters are - added than the maximum (9) .*/ + added than the maximum (9). */ BOOL hb_evalPutParam( PEVALINFO pEvalInfo, PHB_ITEM pItem ) { @@ -471,6 +471,8 @@ PHB_ITEM hb_itemPutCPtr( PHB_ITEM pItem, char * szText, ULONG ulLen ) return pItem; } +/* NOTE: The caller should free the pointer if it's not NULL */ + char * hb_itemGetC( PHB_ITEM pItem ) { HB_TRACE(("hb_itemGetC(%p)", pItem)); @@ -1193,69 +1195,90 @@ char * hb_itemStr( PHB_ITEM pNumber, PHB_ITEM pWidth, PHB_ITEM pDec ) return szResult; } -char * hb_itemString( PHB_ITEM pItem, ULONG * ulLen ) -{ - static char buffer[ 32 ]; /* NOTE: Not re-entrant. Probably not thread safe. */ - char * pointer; +/* NOTE: The caller must free the pointer if the bFreeReq param gets set to + TRUE, this trick is required to stay thread safe, while minimize + memory allocation and buffer copying. + As a side effect the caller should never modify the returned buffer + since it may point to a constant value. [vszel] */ - HB_TRACE(("hb_itemString(%p, %p)", pItem, ulLen)); +char * hb_itemString( PHB_ITEM pItem, ULONG * ulLen, BOOL * bFreeReq ) +{ + char * buffer; + + HB_TRACE(("hb_itemString(%p, %p, %p)", pItem, ulLen, bFreeReq)); switch( pItem->type ) { case IT_STRING: - pointer = hb_itemGetCPtr( pItem ); + buffer = hb_itemGetCPtr( pItem ); * ulLen = hb_itemGetCLen( pItem ); + * bFreeReq = FALSE; break; + case IT_DATE: { char szDate[ 9 ]; + hb_dateDecStr( szDate, pItem->item.asDate.value ); + + buffer = ( char * ) hb_xgrab( 11 ); hb_dtoc( szDate, buffer, hb_set.HB_SET_DATEFORMAT ); - pointer = buffer; * ulLen = strlen( buffer ); + * bFreeReq = TRUE; } break; + case IT_DOUBLE: case IT_INTEGER: case IT_LONG: - pointer = hb_itemStr( pItem, NULL, NULL ); - if( pointer ) + buffer = hb_itemStr( pItem, NULL, NULL ); + if( buffer ) { - strncpy( buffer, pointer, sizeof( buffer ) ); - buffer[ sizeof( buffer ) - 1 ] = '\0'; - hb_xfree( pointer ); - pointer = buffer; * ulLen = strlen( buffer ); + * bFreeReq = TRUE; + } + else + { + buffer = ""; + * ulLen = 0; + * bFreeReq = FALSE; } break; + case IT_NIL: - strcpy( buffer, "NIL" ); - pointer = buffer; + buffer = "NIL"; * ulLen = 3; + * bFreeReq = FALSE; break; + case IT_LOGICAL: - if( hb_itemGetL( pItem ) ) - strcpy( buffer, ".T." ); - else - strcpy( buffer, ".F." ); - pointer = buffer; + buffer = ( hb_itemGetL( pItem ) ? ".T." : ".F." ); * ulLen = 3; + * bFreeReq = FALSE; break; + default: - buffer[ 0 ] = '\0'; - pointer = buffer; + buffer = ""; * ulLen = 0; + * bFreeReq = FALSE; } - return pointer; + + return buffer; } PHB_ITEM hb_itemValToStr( PHB_ITEM pItem ) { + PHB_ITEM pResult; + char * buffer; ULONG ulLen; - char * pointer; + BOOL bFreeReq; HB_TRACE(("hb_itemValToStr(%p)", pItem)); - pointer = hb_itemString( pItem, &ulLen ); - return hb_itemPutCL( NULL, pointer, ulLen ); + buffer = hb_itemString( pItem, &ulLen, &bFreeReq ); + pResult = hb_itemPutCL( NULL, buffer, ulLen ); + if( bFreeReq ) + hb_xfree( buffer ); + + return pResult; } diff --git a/harbour/source/rtl/memvars.c b/harbour/source/rtl/memvars.c index c1f5a5d1a1..cb4931d17d 100644 --- a/harbour/source/rtl/memvars.c +++ b/harbour/source/rtl/memvars.c @@ -550,7 +550,7 @@ static void hb_memvarCreateFromItem( PHB_ITEM pMemvar, BYTE bScope, PHB_ITEM pVa { PHB_DYNS pDynVar; - HB_TRACE(("hb_memvarCreateFromItem(%p, %c, %p)", pMemvar, bScope, pValue)); + HB_TRACE(("hb_memvarCreateFromItem(%p, %d, %p)", pMemvar, bScope, pValue)); /* find dynamic symbol or creeate one */ if( IS_SYMBOL( pMemvar ) ) @@ -566,7 +566,7 @@ static void hb_memvarCreateFromItem( PHB_ITEM pMemvar, BYTE bScope, PHB_ITEM pVa static void hb_memvarCreateFromDynSymbol( PHB_DYNS pDynVar, BYTE bScope, PHB_ITEM pValue ) { - HB_TRACE(("hb_memvarCreateFromDynSymbol(%p, %c, %p)", pDynVar, bScope, pValue)); + HB_TRACE(("hb_memvarCreateFromDynSymbol(%p, %d, %p)", pDynVar, bScope, pValue)); if( bScope & VS_PUBLIC ) { diff --git a/harbour/source/rtl/strings.c b/harbour/source/rtl/strings.c index ba6ece0782..85b2b87451 100644 --- a/harbour/source/rtl/strings.c +++ b/harbour/source/rtl/strings.c @@ -410,7 +410,7 @@ static char * hb_itemPadConv( PHB_ITEM pItem, char * buffer, ULONG * pulSize ) { char * szText; - HB_TRACE(("hb_itemPadCond(%p, %s, %p)", pItem, buffer, pulSize)); + HB_TRACE(("hb_itemPadCond(%p, %p, %p)", pItem, buffer, pulSize)); if( pItem ) { @@ -948,7 +948,7 @@ char * hb_strncpyUpper( char * pDest, char * pSource, ULONG ulLen ) { char * pStart = pDest; - HB_TRACE(("hb_strncpyUpper(%s, %s, %lu)", pDest, pSource, ulLen)); + HB_TRACE(("hb_strncpyUpper(%p, %s, %lu)", pDest, pSource, ulLen)); pDest[ ulLen ] ='\0'; while( ulLen-- ) @@ -1673,6 +1673,11 @@ int hb_strgreater( char * szText1, char * szText2 ) HARBOUR HB_HB_VALTOSTR( void ) { ULONG ulLen; - char * pointer = hb_itemString( hb_param( 1, IT_ANY ), &ulLen ); - hb_retclen( pointer, ulLen ); + BOOL bFreeReq; + char * buffer = hb_itemString( hb_param( 1, IT_ANY ), &ulLen, &bFreeReq ); + + hb_retclen( buffer, ulLen ); + + if( bFreeReq ) + hb_xfree( buffer ); } diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index f1436cb2c3..be4fa41039 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -537,6 +537,9 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols ) break; case HB_P_LINE: + + HB_TRACE(("Opcode: HB_P_LINE: %s (%i)", hb_stack.pBase->item.asSymbol.value->szName, hb_stack.pBase->item.asSymbol.lineno)); + hb_stack.pBase->item.asSymbol.lineno = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ); if( s_bDebugging && s_bDebugShowLines ) hb_vmDebuggerShowLine( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) );