diff --git a/ChangeLog.txt b/ChangeLog.txt index 9cf20181c2..6c6bf96517 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -10,6 +10,50 @@ * Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment */ +2014-12-12 13:30 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + * include/hbcompdf.h + * include/hbexprb.c + * src/common/funcid.c + * src/vm/hvm.c + % optimize Array() function by replacing function call with HB_P_ARRAYDIM + PCODE. Because this optimization changes RTE and interacts with broken + code like + aVal := Array( 10, 0, "A" ) + then it's not enabled by default. User can enable it by -ko switch. + + * utils/hbtest/rt_array.prg + * use #pragma -ko- to for tests which interacts with above modification + + * src/rtl/hbproces.c + % optimize memory allocation for redirected STDOUT and STDERR buffers in + hb_processRun() function. + The previous implementation was extremly inneficient when + hb_processRun() was used to extract very long output from + child process. + + * src/rtl/hbtoken.c + + added support for dividing text into lines using EOLs used by different + platform. To enable it it's enough to specify .T. as delimiter. + + * src/rtl/filesys.c + * pacified MSVC warning - in fact this modification is significant only + for bugy code which changes current directory in MT programs. It's bug + on all platforms using current directory as process not thread + attribute (common behavior). + + * include/inkey.ch + * src/rtl/hbgtcore.c + + added new extended keycodes: + HB_K_TERMINATE + HB_K_MENU + + * contrib/gtqtc/gtqtc1.cpp + + center and rescale to console window dimension keeping aspect size ratio + picture passed to HB_GTI_DISPIMAGE when second parameter is .T. + + added support for HB_K_MENU key + ! fixed dynamic font size modification in fullscreen, maximized and + HB_GTI_RESIZEMODE_ROWS modes + 2014-12-05 01:33 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * src/common/hbffind.c * src/common/hbfsapi.c diff --git a/contrib/gtqtc/gtqtc1.cpp b/contrib/gtqtc/gtqtc1.cpp index f91355c71a..1dd2ad9cc3 100644 --- a/contrib/gtqtc/gtqtc1.cpp +++ b/contrib/gtqtc/gtqtc1.cpp @@ -2357,6 +2357,15 @@ static HB_BOOL hb_gt_qtc_Info( PHB_GT pGT, int iType, PHB_GT_INFO pInfo ) hb_arrayGetNI( pInfo->pNewVal2, 4 ) ); } } + else if( !qImg.isNull() && hb_itemGetL( pInfo->pNewVal2 ) ) + { + iVal = qImg.height() * rx.width() / qImg.width(); + if( iVal <= rx.height() ) + rx.setHeight( iVal ); + else + rx.setWidth( qImg.width() * rx.height() / qImg.height() ); + rx.moveCenter( pQTC->qWnd->qConsole->image->rect().center() ); + } if( qImg.isNull() ) pQTC->qWnd->qConsole->repaintChars( rx ); @@ -2677,7 +2686,14 @@ void QTConsole::setFontSize( int iFH, int iFW ) pQTC->cellY = pQTC->fontHeight; if( pQTC->fRepaint ) + { hb_gt_qtc_resetBoxCharBitmaps( pQTC ); + if( ! image->isNull() && + ( pQTC->iResizeMode == HB_GTI_RESIZEMODE_ROWS || + ( pQTC->qWnd->windowState() & ( Qt::WindowMaximized | Qt::WindowFullScreen ) ) != 0 ) ) + hb_gt_qtc_setWindowSize( pQTC, image->height() / pQTC->cellY, + image->width() / pQTC->cellX ); + } setImageSize(); } @@ -3289,6 +3305,9 @@ void QTConsole::keyPressEvent( QKeyEvent * event ) } iKey = HB_KX_ENTER; break; + case Qt::Key_Menu: + hb_gt_qtc_addKeyToInputQueue( pQTC, HB_K_MENU ); + break; case Qt::Key_Clear: iKey = HB_KX_CENTER; break; diff --git a/include/hbcompdf.h b/include/hbcompdf.h index 4639894a96..374c87730e 100644 --- a/include/hbcompdf.h +++ b/include/hbcompdf.h @@ -248,6 +248,7 @@ typedef enum HB_F_UDF = 0, HB_F_AADD, HB_F_ABS, + HB_F_ARRAY, HB_F_ASC, HB_F_AT, HB_F_BOF, diff --git a/include/hbexprb.c b/include/hbexprb.c index 1cfee8f1c9..e71b76fa19 100644 --- a/include/hbexprb.c +++ b/include/hbexprb.c @@ -2130,6 +2130,14 @@ static HB_EXPR_FUNC( hb_compExprUseFunCall ) HB_GEN_FUNC1( PCode1, HB_P_PUSHAPARAMS ); break; } + else if( pSelf->value.asFunCall.pFunName->value.asSymbol.funcid == HB_F_ARRAY && + HB_SUPPORT_EXTOPT ) + { + if( usCount ) + HB_EXPR_USE( pSelf->value.asFunCall.pParms, HB_EA_PUSH_PCODE ); + HB_GEN_FUNC3( PCode3, HB_P_ARRAYDIM, HB_LOBYTE( usCount ), HB_HIBYTE( usCount ) ); + break; + } } HB_GEN_FUNC2( PushFunCall, pSelf->value.asFunCall.pFunName->value.asSymbol.name, pSelf->value.asFunCall.pFunName->value.asSymbol.flags ); diff --git a/include/inkey.ch b/include/inkey.ch index e510da8d29..3f5b0c6ce9 100644 --- a/include/inkey.ch +++ b/include/inkey.ch @@ -100,6 +100,8 @@ #define HB_K_LOSTFOCUS 1104 #define HB_K_CONNECT 1105 #define HB_K_DISCONNECT 1106 +#define HB_K_TERMINATE 1107 +#define HB_K_MENU 1108 /* Cursor movement keys */ diff --git a/src/common/funcid.c b/src/common/funcid.c index cf9fcccfae..f18bf3ca65 100644 --- a/src/common/funcid.c +++ b/src/common/funcid.c @@ -62,6 +62,7 @@ static _HB_FUNCID s_funcId[] = { { "AADD", 0, HB_FN_RESERVED, HB_F_AADD }, { "ABS", 0, HB_FN_RESERVED, HB_F_ABS }, + { "ARRAY", 0, HB_FN_UDF, HB_F_ARRAY }, { "ASC", 0, HB_FN_RESERVED, HB_F_ASC }, { "AT", 0, HB_FN_RESERVED, HB_F_AT }, { "BOF", 0, HB_FN_RESERVED, HB_F_BOF }, diff --git a/src/rtl/filesys.c b/src/rtl/filesys.c index 7a9e01e0b6..29bbe85911 100644 --- a/src/rtl/filesys.c +++ b/src/rtl/filesys.c @@ -352,17 +352,20 @@ static int fs_win_get_drive( void ) { TCHAR pBuffer[ HB_PATH_MAX ]; LPTSTR lpBuffer = pBuffer; - DWORD dwResult; + DWORD dwResult, dwSize; int iDrive = 0; - dwResult = GetCurrentDirectory( HB_SIZEOFARRAY( pBuffer ), lpBuffer ); - if( dwResult > HB_SIZEOFARRAY( pBuffer ) ) + dwSize = HB_SIZEOFARRAY( pBuffer ); + dwResult = GetCurrentDirectory( dwSize, lpBuffer ); + if( dwResult > dwSize ) { - lpBuffer = ( TCHAR * ) hb_xgrab( dwResult * sizeof( TCHAR ) ); - dwResult = GetCurrentDirectory( dwResult, lpBuffer ); + dwSize = dwResult; + lpBuffer = ( TCHAR * ) hb_xgrab( dwSize * sizeof( TCHAR ) ); + dwResult = GetCurrentDirectory( dwSize, lpBuffer ); } hb_fsSetIOError( dwResult != 0, 0 ); - if( dwResult >= 2 && lpBuffer[ 1 ] == HB_OS_DRIVE_DELIM_CHR ) + if( dwResult >= 2 && dwResult < dwSize && + lpBuffer[ 1 ] == HB_OS_DRIVE_DELIM_CHR ) { iDrive = HB_TOUPPER( lpBuffer[ 0 ] ); if( iDrive >= 'A' && iDrive <= 'Z' ) diff --git a/src/rtl/hbgtcore.c b/src/rtl/hbgtcore.c index 0c1f485fc8..8a3265bbdf 100644 --- a/src/rtl/hbgtcore.c +++ b/src/rtl/hbgtcore.c @@ -2707,6 +2707,8 @@ static int hb_gt_def_InkeyFilter( PHB_GT pGT, int iKey, int iEventMask ) case HB_K_LOSTFOCUS: case HB_K_CONNECT: case HB_K_DISCONNECT: + case HB_K_TERMINATE: + case HB_K_MENU: iMask = HB_INKEY_GTEVENT; break; default: diff --git a/src/rtl/hbproces.c b/src/rtl/hbproces.c index 22984e1e3e..378f2fa222 100644 --- a/src/rtl/hbproces.c +++ b/src/rtl/hbproces.c @@ -1026,7 +1026,10 @@ int hb_fsProcessRun( const char * pszFileName, { if( nOutBuf == nOutSize ) { - nOutSize += HB_STD_BUFFER_SIZE; + if( nOutSize == 0 ) + nOutSize = HB_STD_BUFFER_SIZE; + else + nOutSize += nOutSize >> 1; pOutBuf = ( char * ) hb_xrealloc( pOutBuf, nOutSize + 1 ); } nLen = hb_fsReadLarge( hStdout, pOutBuf + nOutBuf, nOutSize - nOutBuf ); @@ -1045,7 +1048,10 @@ int hb_fsProcessRun( const char * pszFileName, { if( nErrBuf == nErrSize ) { - nErrSize += HB_STD_BUFFER_SIZE; + if( nErrSize == 0 ) + nErrSize = HB_STD_BUFFER_SIZE; + else + nErrSize += nErrSize >> 1; pErrBuf = ( char * ) hb_xrealloc( pErrBuf, nErrSize + 1 ); } nLen = hb_fsReadLarge( hStderr, pErrBuf + nErrBuf, nErrSize - nErrBuf ); @@ -1163,7 +1169,10 @@ int hb_fsProcessRun( const char * pszFileName, { if( nOutBuf == nOutSize ) { - nOutSize += HB_STD_BUFFER_SIZE; + if( nOutSize == 0 ) + nOutSize = HB_STD_BUFFER_SIZE; + else + nOutSize += nOutSize >> 1; pOutBuf = ( char * ) hb_xrealloc( pOutBuf, nOutSize + 1 ); } ul = hb_fsReadLarge( hStdout, pOutBuf + nOutBuf, nOutSize - nOutBuf ); @@ -1183,7 +1192,10 @@ int hb_fsProcessRun( const char * pszFileName, { if( nErrBuf == nErrSize ) { - nErrSize += HB_STD_BUFFER_SIZE; + if( nErrSize == 0 ) + nErrSize = HB_STD_BUFFER_SIZE; + else + nErrSize += nErrSize >> 1; pErrBuf = ( char * ) hb_xrealloc( pErrBuf, nErrSize + 1 ); } ul = hb_fsReadLarge( hStderr, pErrBuf + nErrBuf, nErrSize - nErrBuf ); diff --git a/src/rtl/hbtoken.c b/src/rtl/hbtoken.c index 7c71ebe3c4..abec06c6fb 100644 --- a/src/rtl/hbtoken.c +++ b/src/rtl/hbtoken.c @@ -50,11 +50,13 @@ #include "hbapiitm.h" #include "hbapierr.h" -#define _HB_TOK_RESPECT_DQUOTE 1 -#define _HB_TOK_RESPECT_SQUOTE 2 -#define _HB_TOK_RESPECT_BQUOTE 4 -#define _HB_TOK_ISDELIM 8 -#define _HB_TOK_STRIP_QUUTE 16 +#define _HB_TOK_QUOTE_MASK 0x07 +#define _HB_TOK_RESPECT_DQUOTE 0x01 +#define _HB_TOK_RESPECT_SQUOTE 0x02 +#define _HB_TOK_RESPECT_BQUOTE 0x04 +#define _HB_TOK_ISDELIM 0x08 +#define _HB_TOK_EOL_DELIM 0x10 +#define _HB_TOK_STRIP_QUUTE 0x20 static HB_SIZE hb_tokenCount( const char * szLine, HB_SIZE nLen, const char * szDelim, HB_SIZE nDelim, @@ -65,16 +67,26 @@ static HB_SIZE hb_tokenCount( const char * szLine, HB_SIZE nLen, while( ul < nLen ) { + char ch = szLine[ ul ]; + if( cQuote ) { - if( szLine[ ul ] == cQuote ) + if( ch == cQuote ) cQuote = 0; } - else if( ( szLine[ ul ] == '"' && ( iFlags & _HB_TOK_RESPECT_DQUOTE ) ) || - ( szLine[ ul ] == '\'' && ( iFlags & _HB_TOK_RESPECT_SQUOTE ) ) || - ( szLine[ ul ] == '`' && ( iFlags & _HB_TOK_RESPECT_BQUOTE ) ) ) - cQuote = szLine[ ul ]; - else if( szLine[ ul ] == szDelim[ 0 ] && + else if( ( iFlags & _HB_TOK_QUOTE_MASK ) != 0 && + ( ( ch == '"' && ( iFlags & _HB_TOK_RESPECT_DQUOTE ) ) || + ( ch == '\'' && ( iFlags & _HB_TOK_RESPECT_SQUOTE ) ) || + ( ch == '`' && ( iFlags & _HB_TOK_RESPECT_BQUOTE ) ) ) ) + cQuote = ch; + else if( ( iFlags & _HB_TOK_EOL_DELIM ) != 0 && + ( ch == '\n' || ch == '\r' ) ) + { + ++nTokens; + if( ul + 1 < nLen && szLine[ ul + 1 ] == ( ch == '\n' ? '\r' : '\n' ) ) + ++ul; + } + else if( nDelim && ch == szDelim[ 0 ] && ( nDelim == 1 || ! memcmp( szLine + ul, szDelim, nDelim ) ) ) { ++nTokens; @@ -100,16 +112,31 @@ static const char * hb_tokenGet( const char * szLine, HB_SIZE nLen, for( ul = nStart = 0; ul < nLen; ++ul ) { + char ch = szLine[ ul ]; + if( cQuote ) { - if( szLine[ ul ] == cQuote ) + if( ch == cQuote ) cQuote = 0; } - else if( ( szLine[ ul ] == '"' && ( iFlags & _HB_TOK_RESPECT_DQUOTE ) ) || - ( szLine[ ul ] == '\'' && ( iFlags & _HB_TOK_RESPECT_SQUOTE ) ) || - ( szLine[ ul ] == '`' && ( iFlags & _HB_TOK_RESPECT_BQUOTE ) ) ) - cQuote = szLine[ ul ]; - else if( szLine[ ul ] == szDelim[ 0 ] && + else if( ( iFlags & _HB_TOK_QUOTE_MASK ) != 0 && + ( ( ch == '"' && ( iFlags & _HB_TOK_RESPECT_DQUOTE ) ) || + ( ch == '\'' && ( iFlags & _HB_TOK_RESPECT_SQUOTE ) ) || + ( ch == '`' && ( iFlags & _HB_TOK_RESPECT_BQUOTE ) ) ) ) + cQuote = ch; + else if( ( iFlags & _HB_TOK_EOL_DELIM ) != 0 && + ( ch == '\n' || ch == '\r' ) ) + { + if( --nToken == 0 ) + { + *pnLen = ul - nStart; + return szLine + nStart; + } + if( ul + 1 < nLen && szLine[ ul + 1 ] == ( ch == '\n' ? '\r' : '\n' ) ) + ++ul; + nStart = ul + 1; + } + else if( nDelim && ch == szDelim[ 0 ] && ( nDelim == 1 || ! memcmp( szLine + ul, szDelim, nDelim ) ) ) { if( --nToken == 0 ) @@ -149,16 +176,27 @@ static PHB_ITEM hb_tokenArray( const char * szLine, HB_SIZE nLen, for( ul = nStart = nToken = 0; ul < nLen; ++ul ) { + char ch = szLine[ ul ]; + if( cQuote ) { - if( szLine[ ul ] == cQuote ) + if( ch == cQuote ) cQuote = 0; } - else if( ( szLine[ ul ] == '"' && ( iFlags & _HB_TOK_RESPECT_DQUOTE ) ) || - ( szLine[ ul ] == '\'' && ( iFlags & _HB_TOK_RESPECT_SQUOTE ) ) || - ( szLine[ ul ] == '`' && ( iFlags & _HB_TOK_RESPECT_BQUOTE ) ) ) - cQuote = szLine[ ul ]; - else if( szLine[ ul ] == szDelim[ 0 ] && + else if( ( iFlags & _HB_TOK_QUOTE_MASK ) != 0 && + ( ( ch == '"' && ( iFlags & _HB_TOK_RESPECT_DQUOTE ) ) || + ( ch == '\'' && ( iFlags & _HB_TOK_RESPECT_SQUOTE ) ) || + ( ch == '`' && ( iFlags & _HB_TOK_RESPECT_BQUOTE ) ) ) ) + cQuote = ch; + else if( ( iFlags & _HB_TOK_EOL_DELIM ) != 0 && + ( ch == '\n' || ch == '\r' ) ) + { + hb_arraySetCL( pArray, ++nToken, szLine + nStart, ul - nStart ); + if( ul + 1 < nLen && szLine[ ul + 1 ] == ( ch == '\n' ? '\r' : '\n' ) ) + ++ul; + nStart = ul + 1; + } + else if( nDelim && ch == szDelim[ 0 ] && ( nDelim == 1 || ! memcmp( szLine + ul, szDelim, nDelim ) ) ) { hb_arraySetCL( pArray, ++nToken, szLine + nStart, ul - nStart ); @@ -203,13 +241,17 @@ static HB_BOOL hb_tokenParam( int iParam, HB_SIZE nSkip, szDelim = hb_parc( iParam ); iFlags |= _HB_TOK_ISDELIM; } + else if( hb_parl( iParam ) ) + { + iFlags |= _HB_TOK_EOL_DELIM; + } else { szDelim = " "; nDelim = 1; } - if( ( iFlags & _HB_TOK_ISDELIM ) == 0 ) + if( nDelim && ( iFlags & _HB_TOK_ISDELIM ) == 0 ) { while( nLen && *szLine == szDelim[ 0 ] ) { diff --git a/src/vm/hvm.c b/src/vm/hvm.c index 3edd0c6f1b..640013d092 100644 --- a/src/vm/hvm.c +++ b/src/vm/hvm.c @@ -5500,13 +5500,18 @@ static void hb_vmArrayDim( HB_USHORT uiDimensions ) /* generates an uiDimensions HB_TRACE( HB_TR_DEBUG, ( "hb_vmArrayDim(%hu)", uiDimensions ) ); - hb_vmArrayNew( hb_stackAllocItem(), uiDimensions ); + if( uiDimensions ) + { + hb_vmArrayNew( hb_stackAllocItem(), uiDimensions ); - hb_itemMove( hb_stackItemFromTop( ( int ) ( -1 - uiDimensions ) ), - hb_stackItemFromTop( -1 ) ); - do - hb_stackPop(); - while( --uiDimensions ); + hb_itemMove( hb_stackItemFromTop( ( int ) ( -1 - uiDimensions ) ), + hb_stackItemFromTop( -1 ) ); + do + hb_stackPop(); + while( --uiDimensions ); + } + else + HB_VM_PUSHNIL(); } static void hb_vmHashGen( HB_SIZE nElements ) /* generates an nElements Hash and fills it from the stack values */ diff --git a/utils/hbtest/rt_array.prg b/utils/hbtest/rt_array.prg index e43639ab2c..286308fa19 100644 --- a/utils/hbtest/rt_array.prg +++ b/utils/hbtest/rt_array.prg @@ -208,8 +208,15 @@ PROCEDURE Main_ARRAY() #endif HBTEST Array( 1 ) IS "{.[1].}" HBTEST Array( -1 ) IS "E 2 BASE 1131 Bound error (array dimension) OS:0 #:0 " +#ifdef __HARBOUR__ + /* disable Harbour extended optimizations to test correct RTE message */ + #pragma -ko- +#endif HBTEST Array( 1, 0, -10 ) IS "E 2 BASE 1131 Bound error (array dimension) OS:0 #:0 " HBTEST Array( 1, 0, "A" ) IS NIL +#ifdef __HARBOUR__ + #pragma -ko+ +#endif HBTEST Array( 1, 0, 2 ) IS "{.[1].}" HBTEST Array( 4, 3, 2 ) IS "{.[4].}" HBTEST Array( 0, 3, 2 ) IS "{.[0].}"