From ff1288dc3f4ce86004065ae739b7d2daf4dc6a59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Czerpak?= Date: Tue, 4 Nov 2014 01:54:04 +0100 Subject: [PATCH] 2014-11-04 01:54 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * ChangeLog.txt * doc/xhb-diff.txt ! typos * doc/clipper.txt ! removed completely false information about 'LIST &cMacro' * updated information about FOR EACH ; in general information in this file are outdated and does not correctly describe current Harbour behavior. I strongly suggest to not use it in any other documentation. In some spare time I'll update this file or remove. * doc/cmpopt.txt + added information about unsupported by Clipper syntax extension: iif( , , ) = * include/hbrddnsx.h * minor modification in comment * src/macro/macrolex.c * accept unconditionally hash 'key => value' operator * src/rdd/dbfnsx/dbfnsx1.c ! fixed very bad bug in leaf key compression. This problem could be exploited by keys containing containing CHR( 255 ) in encoded keys just before trailing empty key characters. This bug could cause index corruption. * use hb_xgrabz() * formatting --- ChangeLog.txt | 33 ++++++++- doc/clipper.txt | 55 ++++++++------- doc/cmpopt.txt | 14 ++++ doc/xhb-diff.txt | 2 +- include/hbrddnsx.h | 6 +- src/macro/macrolex.c | 2 +- src/rdd/dbfnsx/dbfnsx1.c | 149 ++++++++++++++++++--------------------- 7 files changed, 149 insertions(+), 112 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 92c7709568..d0bdab4707 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -10,6 +10,37 @@ * Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment */ +2014-11-04 01:54 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + * ChangeLog.txt + * doc/xhb-diff.txt + ! typos + + * doc/clipper.txt + ! removed completely false information about 'LIST &cMacro' + * updated information about FOR EACH + ; in general information in this file are outdated and does not + correctly describe current Harbour behavior. I strongly suggest + to not use it in any other documentation. In some spare time + I'll update this file or remove. + + * doc/cmpopt.txt + + added information about unsupported by Clipper syntax extension: + iif( , , ) = + + * include/hbrddnsx.h + * minor modification in comment + + * src/macro/macrolex.c + * accept unconditionally hash 'key => value' operator + + * src/rdd/dbfnsx/dbfnsx1.c + ! fixed very bad bug in leaf key compression. This problem could be + exploited by keys containing containing CHR( 255 ) in encoded keys + just before trailing empty key characters. + This bug could cause index corruption. + * use hb_xgrabz() + * formatting + 2014-10-28 16:06 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * doc/xhb-diff.txt * updated information about extended CDX format and defined by user @@ -22555,7 +22586,7 @@ + added new harbour compiler switch: -kd => accept macros with declared symbols This switch allows to use declared symbols like LOCALs, STATICs - and FIELDs in macros and macrocodeblocks (every evaluated). + and FIELDs in macros and macrocodeblocks (early evaluated). ; Please do not confuse different things. Above modification does not mean to that such variables are visible for macro compiler. It only allows to write code like: diff --git a/doc/clipper.txt b/doc/clipper.txt index c4b22385d3..1a8412bcde 100644 --- a/doc/clipper.txt +++ b/doc/clipper.txt @@ -30,23 +30,6 @@ Both these extra layers are activated by default. * See also -k Compiler switch. -LIST Command ------------- - -LIST &cMacro - -LIST in CA-Cl*pper [superficially] supports macros of lists expressions. -No error will be produced, and all expressions in the list will be -evaluated, but *only* the *last* expression will be displayed. This is -not documented in either the LIST Command or the Macro Operator -descriptions, but is the de-facto behavior in all CA-Cl*pper 5.x versions. - -Harbour instead will not only evaluate all of the expressions in -such list macro, but will also display all such values. This default -behavior may be disabled with hb_SetMacro( HB_SM_XBASE, .F. )* - -* See also -k Compiler switch. - INIT/EXIT and startup procedures -------------------------------- @@ -67,17 +50,37 @@ Harbour has support enumeration loop with the following syntax: NEXT Note: - - expr can be a string or an array + - expr can be a string, an array, an hash array or an object with + custom FOR EACH action - enumerator variable 'var' stores a reference to the element of - an array or a string specified by 'expr' thus assigments to the - enumerator changes the value of given array element - - after the loop the controlling variable(s) store the value which + an hash, array or a string specified by 'expr' thus assignments + to the enumerator changes the value of given element of iterated + item. If FOR EACH is used to iterate string items them assignment + to enumerator item changes the original string only if it was passed + to FOR EACH statement by reference, i.e.: + FOR EACH c IN @string + IF ! isAlpha( c ) + c := "*" + ELSE + c := upper( c ) + ENDIF + NEXT + - after the loop the controlling variable(s) restore the value which they had before entering the loop - - the enumeraqtor variable supports the following properties - :__enumindex - the loop counter for variable - :__enumbase - the value that is being traversed - :__enumvalue - the value of variable - + - the enumerator variable supports the following properties + :__enumIndex - the loop counter for variable + :__enumKey - the hash key value of traversed hash item pair + :__enumBase - the value that is being traversed + :__enumValue - the value of variable + :__enumIsFirst - is it the first enumerated item? + :__enumIsLast - is it the last enumerated item? + - defining new class or overloading existing one user can define + his own behavior of FOR EACH iterating overloading chosen of above + methods and/or the following ones: + :__enumStart + :__enumSkip + :__enumStop + By default FOR EACH iterate all object instance variables for example: a := 'A' diff --git a/doc/cmpopt.txt b/doc/cmpopt.txt index 298d76f73f..862bf95add 100644 --- a/doc/cmpopt.txt +++ b/doc/cmpopt.txt @@ -146,6 +146,20 @@ arguments are well known and can be calculated at compile time: ( ) => // it allows to optimize // expresions like: 1+(2) + - Harbour syntax extensions not supported by Clipper, enabled by -ko + compiler switch: + iif( , , ) = => ; + IF ; + = ; + ELSE ; + = ; + ENDIF + i.e.: + iif( dData == NIL, dDate, aVal[ 1 ] ) := date() + iif( empty( x ), aVal[ 2 ], nTmp ) += 10 + ? iif( f1(), nVal1, nVal2 ) ++ + ? -- iif( f2(), aVal[ 1 ], hVal[ "abc" ] ) + - Harbour extensions which may disable RT errors in wrong expressions or can change used operators using basic math rules. Enabled by -ko compiler switch: diff --git a/doc/xhb-diff.txt b/doc/xhb-diff.txt index 3d3e8a9c63..cabeafc360 100644 --- a/doc/xhb-diff.txt +++ b/doc/xhb-diff.txt @@ -121,7 +121,7 @@ file system(s) and with different OS(s). "=>", x:__enumBase()[ x:__enumKey() ] NEXT f) it gives very flexible OOP mechanism to overload FOR EACH behavior - for user define objects adding to above enumerator methods also + for user defined classes adding to above enumerator methods also __enumStart(), __enumStop(), __enumSkip() methods what allows to implement many different enumeration algorithms depending on used data diff --git a/include/hbrddnsx.h b/include/hbrddnsx.h index 94474cf40b..ce8b3c3365 100644 --- a/include/hbrddnsx.h +++ b/include/hbrddnsx.h @@ -335,11 +335,11 @@ typedef struct _NSXLEAFKEY * if Size == n + 1 then key is fully duplicated */ HB_UCHAR DupCount[1]; /* number of bytes from previous key */ - HB_UCHAR KeyData[l]; /* rest of key value with RLE compression: + HB_UCHAR KeyData[m]; /* rest of key value with RLE compression: * FF xx yy => Replicate(yy, xx) * FF 01 => FF - * l = Size - n - 2 - * if l == KEY_SIZE - DupCount then key value + * m = Size - n - 2 + * if m == KEY_SIZE - DupCount then key value * is stored as raw data and can be copied as is * if after decompression size of key value is * smaller then KEY_SIZE then rest if filled with diff --git a/src/macro/macrolex.c b/src/macro/macrolex.c index bfd8b5f776..5e89da1042 100644 --- a/src/macro/macrolex.c +++ b/src/macro/macrolex.c @@ -338,7 +338,7 @@ int hb_macro_yylex( YYSTYPE * yylval_ptr, PHB_MACRO pMacro ) pLex->nSrc++; return EQ; } - else if( pLex->pString[ pLex->nSrc ] == '>' && HB_SUPPORT_HARBOUR ) + else if( pLex->pString[ pLex->nSrc ] == '>' ) { pLex->nSrc++; return HASHOP; diff --git a/src/rdd/dbfnsx/dbfnsx1.c b/src/rdd/dbfnsx/dbfnsx1.c index 717b116be1..42a53c65b5 100644 --- a/src/rdd/dbfnsx/dbfnsx1.c +++ b/src/rdd/dbfnsx/dbfnsx1.c @@ -341,9 +341,9 @@ static HB_USHORT hb_nsxLeafPutKey( LPTAGINFO pTag, LPPAGEINFO pPage, HB_USHORT u HB_UCHAR * bPrevValue, HB_UCHAR * pKeyValue, HB_ULONG ulRecNo ) { HB_UCHAR * ptr = ( HB_UCHAR * ) hb_nsxPageBuffer( pPage ) + uiOffset, - * pDst, * pSrc, * pEnd; + * pDst, * pSrc, * pEnd; HB_UCHAR ucSize = hb_nsxGetKeyRecSize( pPage ), ucDupCount = 0, - ucLen = ( HB_UCHAR ) pTag->KeyLength; + ucLen = ( HB_UCHAR ) pTag->KeyLength; int iMax; if( uiOffset + ucSize >= NSX_PAGELEN ) @@ -401,70 +401,68 @@ static HB_USHORT hb_nsxLeafPutKey( LPTAGINFO pTag, LPPAGEINFO pPage, HB_USHORT u } pDst = ptr + 2; - iMax = NSX_PAGELEN - uiOffset - ucSize; - if( iMax >= ( int ) ucLen ) - iMax = ucLen - 1; - - while( iMax > 0 && pSrc < pEnd ) + iMax = NSX_PAGELEN - uiOffset - ucSize + 1; + if( iMax > ( int ) ucLen ) + iMax = ucLen; + if( iMax > 0 ) { - HB_UCHAR uc = *pSrc++; - if( pSrc < pEnd - 2 && uc == *pSrc && uc == pSrc[ 1 ] ) + while( pSrc < pEnd ) { - HB_UCHAR ucRepl = 3; - iMax -= 3; - if( iMax < 0 ) - break; - pSrc += 2; - while( pSrc < pEnd && *pSrc == uc ) + HB_UCHAR uc = *pSrc++; + if( uc == NSX_RLE_CHAR ) { - ++pSrc; - ++ucRepl; + if( pSrc < pEnd && *pSrc == NSX_RLE_CHAR ) + { + HB_UCHAR ucRepl = 2; + if( ( iMax -= 3 ) <= 0 ) + break; + ++pSrc; + while( pSrc < pEnd && *pSrc == NSX_RLE_CHAR ) + { + ++pSrc; + ++ucRepl; + } + *pDst++ = NSX_RLE_CHAR; + *pDst++ = ucRepl; + *pDst++ = NSX_RLE_CHAR; + } + else + { + if( ( iMax -= 2 ) <= 0 ) + break; + *pDst++ = NSX_RLE_CHAR; + *pDst++ = 1; + } } - *pDst++ = NSX_RLE_CHAR; - *pDst++ = ucRepl; - *pDst++ = uc; - } - else if( uc == NSX_RLE_CHAR ) - { - if( pSrc < pEnd && uc == *pSrc ) + else if( pEnd - pSrc > 2 && + *pSrc == uc && pSrc[ 1 ] == uc && pSrc[ 2 ] == uc ) { - HB_UCHAR ucRepl = 2; - iMax -= 3; - if( iMax < 0 ) + HB_UCHAR ucRepl = 4; + if( ( iMax -= 3 ) <= 0 ) break; - ++pSrc; - if( pSrc < pEnd && uc == pSrc[ 1 ] ) + pSrc += 3; + while( pSrc < pEnd && *pSrc == uc ) { ++pSrc; ++ucRepl; } *pDst++ = NSX_RLE_CHAR; *pDst++ = ucRepl; - *pDst++ = NSX_RLE_CHAR; + *pDst++ = uc; } + else if( --iMax == 0 ) + break; else - { - iMax -= 2; - if( iMax < 0 ) - break; - *pDst++ = NSX_RLE_CHAR; - *pDst++ = 1; - } + *pDst++ = uc; } - else + if( iMax > 0 ) { - iMax--; - *pDst++ = uc; + ucSize += ( HB_UCHAR ) ( pDst - ( ptr + 2 ) ); + *ptr = ucSize; + return uiOffset + ucSize; } } - if( pSrc == pEnd ) - { - ucSize += ( HB_UCHAR ) ( pDst - ( ptr + 2 ) ); - *ptr = ucSize; - return uiOffset + ucSize; - } - uiOffset += ucSize + ucLen; if( uiOffset > NSX_PAGELEN ) return 0; @@ -1293,7 +1291,7 @@ static HB_BOOL hb_nsxTagHeaderCheck( LPTAGINFO pTag ) { if( header.Signature[ 0 ] == NSX_SIGNATURE ) { - pTag->TagFlags = header.TagFlags[0]; + pTag->TagFlags = header.TagFlags[ 0 ]; pTag->RootBlock = HB_GET_LE_UINT32( header.RootPage ); hb_nsxTagUpdateFlags( pTag ); } @@ -1414,9 +1412,8 @@ static LPPAGEINFO hb_nsxPageGetBuffer( LPTAGINFO pTag, HB_ULONG ulPage ) pIndex->ulPages = 1; pIndex->ulPageLast = 0; pIndex->ulPagesDepth = NSX_PAGE_BUFFER; - pIndex->pages = ( LPPAGEINFO * ) hb_xgrab( sizeof( LPPAGEINFO ) * NSX_PAGE_BUFFER ); - memset( pIndex->pages, 0, sizeof( LPPAGEINFO ) * NSX_PAGE_BUFFER ); - pPagePtr = &pIndex->pages[0]; + pIndex->pages = ( LPPAGEINFO * ) hb_xgrabz( sizeof( LPPAGEINFO ) * NSX_PAGE_BUFFER ); + pPagePtr = &pIndex->pages[ 0 ]; } else { @@ -1449,14 +1446,12 @@ static LPPAGEINFO hb_nsxPageGetBuffer( LPTAGINFO pTag, HB_ULONG ulPage ) if( ! *pPagePtr ) { - *pPagePtr = ( LPPAGEINFO ) hb_xgrab( sizeof( HB_PAGEINFO ) ); - memset( *pPagePtr, 0, sizeof( HB_PAGEINFO ) ); + *pPagePtr = ( LPPAGEINFO ) hb_xgrabz( sizeof( HB_PAGEINFO ) ); } #ifdef HB_NSX_EXTERNAL_PAGEBUFFER if( ! hb_nsxPageBuffer( *pPagePtr ) ) { - hb_nsxPageBuffer( *pPagePtr ) = ( HB_UCHAR * ) hb_xgrab( NSX_PAGELEN ); - memset( hb_nsxPageBuffer( *pPagePtr ), 0, NSX_PAGELEN ); + hb_nsxPageBuffer( *pPagePtr ) = ( HB_UCHAR * ) hb_xgrabz( NSX_PAGELEN ); } #endif ( *pPagePtr )->pPrev = NULL; @@ -1695,8 +1690,7 @@ static LPTAGINFO hb_nsxTagNew( LPNSXINDEX pIndex, const char * szTagName, { LPTAGINFO pTag; - pTag = ( LPTAGINFO ) hb_xgrab( sizeof( TAGINFO ) ); - memset( pTag, 0, sizeof( TAGINFO ) ); + pTag = ( LPTAGINFO ) hb_xgrabz( sizeof( TAGINFO ) ); pTag->TagName = hb_strndup( szTagName, NSX_TAGNAME ); pTag->pIndex = pIndex; if( szKeyExpr ) @@ -1930,12 +1924,12 @@ static HB_ERRCODE hb_nsxTagHeaderSave( LPTAGINFO pTag ) hb_nsxIndexTagAdd( pIndex, pTag ); } - Header.Signature[0] = NSX_SIGNATURE; - Header.TagFlags[0] = ( pTag->Partial ? NSX_TAG_PARTIAL : 0 ) | - ( pTag->Template ? NSX_TAG_TEMPLATE : 0 ) | - ( pTag->ChgOnly ? NSX_TAG_CHGONLY : 0 ) | - ( pTag->Custom ? NSX_TAG_NOUPDATE : 0 ) | - ( pTag->MultiKey ? NSX_TAG_MULTIKEY : 0 ); + Header.Signature[ 0 ] = NSX_SIGNATURE; + Header.TagFlags[ 0 ] = ( pTag->Partial ? NSX_TAG_PARTIAL : 0 ) | + ( pTag->Template ? NSX_TAG_TEMPLATE : 0 ) | + ( pTag->ChgOnly ? NSX_TAG_CHGONLY : 0 ) | + ( pTag->Custom ? NSX_TAG_NOUPDATE : 0 ) | + ( pTag->MultiKey ? NSX_TAG_MULTIKEY : 0 ); HB_PUT_LE_UINT32( Header.RootPage, pTag->RootBlock ); if( pIndex->Update ) @@ -1948,8 +1942,8 @@ static HB_ERRCODE hb_nsxTagHeaderSave( LPTAGINFO pTag ) HB_PUT_LE_UINT16( Header.KeyType, type ); HB_PUT_LE_UINT16( Header.KeySize, pTag->KeyLength ); - Header.Unique[0] = pTag->UniqueKey ? 1 : 0; - Header.Descend[0] = pTag->AscendKey ? 0 : 1; + Header.Unique[ 0 ] = pTag->UniqueKey ? 1 : 0; + Header.Descend[ 0 ] = pTag->AscendKey ? 0 : 1; iLen = ( int ) strlen( pTag->KeyExpr ); if( iLen > NSX_MAXEXPLEN ) @@ -1981,8 +1975,7 @@ static LPNSXINDEX hb_nsxIndexNew( NSXAREAP pArea ) { LPNSXINDEX pIndex; - pIndex = ( LPNSXINDEX ) hb_xgrab( sizeof( NSXINDEX ) ); - memset( pIndex, 0, sizeof( NSXINDEX ) ); + pIndex = ( LPNSXINDEX ) hb_xgrabz( sizeof( NSXINDEX ) ); pIndex->pFile = NULL; pIndex->pArea = pArea; @@ -2027,9 +2020,9 @@ static HB_ERRCODE hb_nsxIndexHeaderSave( LPNSXINDEX pIndex ) pIndex->Version++; pIndex->Version &= 0xFFFF; - pIndex->HeaderBuff.Signature[0] = pIndex->LargeFile ? - NSX_SIGNATURE_LARGE : NSX_SIGNATURE; - pIndex->HeaderBuff.IndexFlags[0] = 0; + pIndex->HeaderBuff.Signature[ 0 ] = pIndex->LargeFile ? + NSX_SIGNATURE_LARGE : NSX_SIGNATURE; + pIndex->HeaderBuff.IndexFlags[ 0 ] = 0; HB_PUT_LE_UINT16( pIndex->HeaderBuff.TagCount, pIndex->iTags ); HB_PUT_LE_UINT16( pIndex->HeaderBuff.Version, pIndex->Version ); HB_PUT_LE_UINT32( pIndex->HeaderBuff.FreePage, pIndex->NextAvail ); @@ -2487,8 +2480,7 @@ static void hb_nsxTagSetPageStack( LPTAGINFO pTag, LPPAGEINFO pPage, HB_USHORT u if( pTag->stackSize == 0 ) { pTag->stackSize = NSX_STACKSIZE; - pTag->stack = ( LPTREESTACK ) hb_xgrab( sizeof( TREE_STACK ) * NSX_STACKSIZE ); - memset( pTag->stack, 0, sizeof( TREE_STACK ) * NSX_STACKSIZE ); + pTag->stack = ( LPTREESTACK ) hb_xgrabz( sizeof( TREE_STACK ) * NSX_STACKSIZE ); } else { @@ -2556,8 +2548,7 @@ static LPPAGEINFO hb_nsxPageBottomMove( LPTAGINFO pTag, HB_ULONG ulPage ) return NULL; if( hb_nsxIsLeaf( pPage ) ) { - hb_nsxTagSetPageStack( pTag, pPage, pPage->uiKeys - - ( pPage->uiKeys == 0 ? 0 : 1 ) ); + hb_nsxTagSetPageStack( pTag, pPage, ( pPage->uiKeys > 0 ? pPage->uiKeys - 1 : 0 ) ); if( pPage->uiKeys == 0 && pTag->stackLevel > 1 && ! pTag->pIndex->pArea->pSort ) { hb_nsxPageRelease( pTag, pPage ); @@ -5440,8 +5431,7 @@ static LPNSXSORTINFO hb_nsxSortNew( LPTAGINFO pTag, HB_ULONG ulRecCount ) if( ulRecCount == 0 ) ulRecCount = 1; - pSort = ( LPNSXSORTINFO ) hb_xgrab( sizeof( NSXSORTINFO ) ); - memset( pSort, 0, sizeof( NSXSORTINFO ) ); + pSort = ( LPNSXSORTINFO ) hb_xgrabz( sizeof( NSXSORTINFO ) ); ulMin = ( HB_ULONG ) ceil( sqrt( ( double ) ulRecCount ) ); ulMax = ( ( HB_ULONG ) ceil( sqrt( ( double ) ulRecCount / ( iLen + 4 ) ) ) ) << 7; @@ -5512,8 +5502,7 @@ static LPNSXSORTINFO hb_nsxSortNew( LPTAGINFO pTag, HB_ULONG ulRecCount ) /* check for overflow on 32 bit machines when number of records is nearly 2^32 */ if( ! pSort->ulPages ) pSort->ulPages = ulRecCount / pSort->ulPgKeys + 1; - pSort->pSwapPage = ( LPNSXSWAPPAGE ) hb_xgrab( sizeof( NSXSWAPPAGE ) * pSort->ulPages ); - memset( pSort->pSwapPage, 0, sizeof( NSXSWAPPAGE ) * pSort->ulPages ); + pSort->pSwapPage = ( LPNSXSWAPPAGE ) hb_xgrabz( sizeof( NSXSWAPPAGE ) * pSort->ulPages ); return pSort; } @@ -8272,8 +8261,8 @@ HB_CALL_ON_STARTUP_BEGIN( _hb_dbfnsx_rdd_init_ ) HB_CALL_ON_STARTUP_END( _hb_dbfnsx_rdd_init_ ) #if defined( HB_PRAGMA_STARTUP ) -# pragma startup dbfnsx1__InitSymbols -# pragma startup _hb_dbfnsx_rdd_init_ + #pragma startup dbfnsx1__InitSymbols + #pragma startup _hb_dbfnsx_rdd_init_ #elif defined( HB_DATASEG_STARTUP ) #define HB_DATASEG_BODY HB_DATASEG_FUNC( dbfnsx1__InitSymbols ) \ HB_DATASEG_FUNC( _hb_dbfnsx_rdd_init_ )