From 20ec21c5530d88104827ef8c7bd7c99c52eb03ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Czerpak?= Date: Fri, 12 Dec 2014 13:30:56 +0100 Subject: [PATCH] 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 --- ChangeLog.txt | 44 +++++++++++++++++++ contrib/gtqtc/gtqtc1.cpp | 19 +++++++++ include/hbcompdf.h | 1 + include/hbexprb.c | 8 ++++ include/inkey.ch | 2 + src/common/funcid.c | 1 + src/rtl/filesys.c | 15 ++++--- src/rtl/hbgtcore.c | 2 + src/rtl/hbproces.c | 20 +++++++-- src/rtl/hbtoken.c | 90 ++++++++++++++++++++++++++++----------- src/vm/hvm.c | 17 +++++--- utils/hbtest/rt_array.prg | 7 +++ 12 files changed, 186 insertions(+), 40 deletions(-) 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].}"