diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 5f193f2fb5..a9ee8aaefa 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,34 @@ past entries belonging to author(s): Viktor Szakats. */ +2010-01-22 17:26 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) + * contrib/hbwin/hbwapi.h + * contrib/hbwin/wapi_wingdi.c + ! Fixed potential GPD in hbwapi_par/stor*() functions + when parameter was not passed at all. + + Added hbwapi_par_DOCINFO() and hbwapi_strfree_DOCINFO() + pairs to retrieve structures with strings in them. + Hashes are supported now as well. + ; TODO: Low-level string handling functions will GPF + yet if the related hashes are missing (f.e. in + posted test code). This requires proposed extra + guards in low-level string functions. + + WAPI_STARTDOC() changed to use hbwapi_par_DOCINFO(). + % Minor cleanup in WAPI_SELECTOBJECT(). + + + contrib/hbwin/tests/testgdi.prg + + Added test code for GDI function structure parameter exchange. + + * contrib/hbide/idethemes.prg + * contrib/hbide/ideeditor.prg + + Added 'sequence' and 'endsequence' to keywords. + ; TOFIX: try/catch and a few more are not Harbour keywords. + + * contrib/hbide/ideeditor.prg + % Optimized low-level keyword lookup functions: + - Use hashes instead of arrays and ascan. + - Use STATIC vars to avoid rebuilding tables on every call. + 2010-01-22 08:24 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com) * contrib/hbqt/hbqt_hbqplaintextedit.cpp ! Fix to handle unused variable : "txt". diff --git a/harbour/contrib/hbide/ideeditor.prg b/harbour/contrib/hbide/ideeditor.prg index fff602d108..6adbab045d 100644 --- a/harbour/contrib/hbide/ideeditor.prg +++ b/harbour/contrib/hbide/ideeditor.prg @@ -1706,43 +1706,89 @@ METHOD IdeEdit:findLastIndent() /*----------------------------------------------------------------------*/ FUNCTION hbide_isHarbourKeyword( cWord ) - LOCAL b_:= { 'function','return','static','local','default', ; - 'if','else','elseif','endif','end', ; - 'docase','case','endcase','otherwise', ; - 'do','while','exit',; - 'for','each','next','step','to',; - 'class','endclass','method','data','var','destructor','inline','assign','access',; - 'inherit','init','create','virtual','message',; - 'begin','sequence','try','catch','always','recover','hb_symbol_unused', ; - 'error','handler' } + STATIC s_b_ := { 'function' => NIL,; + 'return' => NIL,; + 'static' => NIL,; + 'local' => NIL,; + 'default' => NIL,; + 'if' => NIL,; + 'else' => NIL,; + 'elseif' => NIL,; + 'endif' => NIL,; + 'end' => NIL,; + 'endswitch' => NIL,; + 'docase' => NIL,; + 'case' => NIL,; + 'endcase' => NIL,; + 'otherwise' => NIL,; + 'switch' => NIL,; + 'do' => NIL,; + 'while' => NIL,; + 'exit' => NIL,; + 'for' => NIL,; + 'each' => NIL,; + 'next' => NIL,; + 'step' => NIL,; + 'to' => NIL,; + 'class' => NIL,; + 'endclass' => NIL,; + 'method' => NIL,; + 'data' => NIL,; + 'var' => NIL,; + 'destructor' => NIL,; + 'inline' => NIL,; + 'assign' => NIL,; + 'access' => NIL,; + 'inherit' => NIL,; + 'init' => NIL,; + 'create' => NIL,; + 'virtual' => NIL,; + 'message' => NIL,; + 'begin' => NIL,; + 'sequence' => NIL,; + 'try' => NIL,; + 'catch' => NIL,; + 'always' => NIL,; + 'recover' => NIL,; + 'hb_symbol_unused' => NIL,; + 'error' => NIL,; + 'handler' => NIL } - cWord := lower( cWord ) - - RETURN ascan( b_, {|e| e == cWord } ) > 0 + RETURN Lower( cWord ) $ s_b_ /*----------------------------------------------------------------------*/ FUNCTION hbide_isIndentableKeyword( cWord ) - LOCAL b_:= { 'function',; - 'if','else','elseif', ; - 'docase','case','otherwise', ; - 'do','while',; - 'for',; - 'class','method',; - 'begin','sequence','try','catch','always','recover','finally' } + LOCAL s_b_ := { 'function' => NIL,; + 'if' => NIL,; + 'else' => NIL,; + 'elseif' => NIL,; + 'docase' => NIL,; + 'case' => NIL,; + 'otherwise' => NIL,; + 'do' => NIL,; + 'while' => NIL,; + 'switch' => NIL,; + 'for' => NIL,; + 'class' => NIL,; + 'method' => NIL,; + 'begin' => NIL,; + 'sequence' => NIL,; + 'try' => NIL,; + 'catch' => NIL,; + 'always' => NIL,; + 'recover' => NIL,; + 'finally' => NIL } - cWord := lower( cWord ) - - RETURN ascan( b_, {|e| e == cWord } ) > 0 + RETURN Lower( cWord ) $ s_b_ /*----------------------------------------------------------------------*/ FUNCTION hbide_isStartingKeyword( cWord ) - LOCAL b_:= { 'function','method' } + STATIC s_b_ := { 'function' => NIL,; + 'method' => NIL } - cWord := lower( cWord ) - - RETURN ascan( b_, {|e| e == cWord } ) > 0 + RETURN Lower( cWord ) $ s_b_ /*----------------------------------------------------------------------*/ @@ -1839,5 +1885,3 @@ FUNCTION hbide_getFrontSpacesAndWord( cText, cWord ) RETURN n /*----------------------------------------------------------------------*/ - - diff --git a/harbour/contrib/hbide/idethemes.prg b/harbour/contrib/hbide/idethemes.prg index eeccd72037..909a6868de 100644 --- a/harbour/contrib/hbide/idethemes.prg +++ b/harbour/contrib/hbide/idethemes.prg @@ -178,8 +178,8 @@ METHOD IdeThemes:create( oIde, cIniFile ) /* Harbour Keywords */ b_:= { 'function','return','static','local','default', ; - 'if','else','elseif','endif','end', ; - 'docase','case','endcase','otherwise', ; + 'if','else','elseif','endif','end', 'endswitch', ; + 'docase','case','endcase','otherwise', 'switch', ; 'do','while','exit',; 'for','each','next','step','to',; 'class','endclass','method','data','var','destructor','inline','assign','access',; diff --git a/harbour/contrib/hbwin/hbwapi.h b/harbour/contrib/hbwin/hbwapi.h index 12724d1cfb..0f26d845f6 100644 --- a/harbour/contrib/hbwin/hbwapi.h +++ b/harbour/contrib/hbwin/hbwapi.h @@ -105,6 +105,7 @@ HB_EXPORT DWORD hbwapi_GetLastError( void ); HB_EXPORT POINT * hbwapi_par_POINT( POINT * p, int iParam, HB_BOOL bMandatory ); HB_EXPORT RECT * hbwapi_par_RECT( RECT * p, int iParam, HB_BOOL bMandatory ); HB_EXPORT DEVMODE * hbwapi_par_DEVMODE( DEVMODE * p, int iParam, HB_BOOL bMandatory ); +HB_EXPORT DOCINFO * hbwapi_par_DOCINFO( DOCINFO * p, int iParam, HB_BOOL bMandatory, void *** h ); HB_EXPORT void hbwapi_stor_POINT( POINT * p, int iParam ); HB_EXPORT void hbwapi_stor_RECT( RECT * p, int iParam ); diff --git a/harbour/contrib/hbwin/tests/testgdi.prg b/harbour/contrib/hbwin/tests/testgdi.prg new file mode 100644 index 0000000000..9fefc09043 --- /dev/null +++ b/harbour/contrib/hbwin/tests/testgdi.prg @@ -0,0 +1,71 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * GDI calls and passing structures. + * + * Copyright 2010 Viktor Szakats (harbour.01 syenar.hu) + * www - http://www.harbour-project.org + * + */ + +#include "simpleio.ch" + +#include "hbwin.ch" + +PROCEDURE Main() + LOCAL hDC + LOCAL hDOCINFO + LOCAL hDEVMODE + LOCAL hRECT + LOCAL aRECT + LOCAL hOBJECT + + hDEVMODE := hb_hash() + ? hDC := wapi_CreateDC( NIL, "Microsoft XPS Document Writer", NIL, hDEVMODE ) + + hDOCINFO := hb_hash() + hDOCINFO[ "lpszDocName" ] := "test job" + ? wapi_StartDoc( hDC, hDOCINFO ) + ? wapi_StartPage( hDC ) + ? hOBJECT := wapi_CreateFont( ,,,,,,,,,,,,, "Arial" ) + ? wapi_SelectObject( hDC, hOBJECT ) + + ? "in ARR" + aRECT := { 100, 150, 450, 250 } + ? wapi_DrawText( hDC, "0TEST", aRECT ) + + ? "inout ARR" + aRECT := { 100, 150, 450, 250 } + ? wapi_DrawText( hDC, "1TEST", aRECT, WIN_DT_CALCRECT ) + ? aRECT[ 1 ], aRECT[ 2 ], aRECT[ 3 ], aRECT[ 4 ] + + ? "out HASH" + hRECT := hb_hash() + ? wapi_DrawText( hDC, "2TEST", hRECT, WIN_DT_CALCRECT ) + ? hRECT[ "left" ], hRECT[ "top" ], hRECT[ "bottom" ], hRECT[ "right" ] + + ? "inout HASH" + hRECT := hb_hash() + hRECT[ "left" ] := 300 + hRECT[ "top" ] := 350 + ? wapi_DrawText( hDC, "3TEST", hRECT, WIN_DT_CALCRECT ) + ? hRECT[ "left" ], hRECT[ "top" ], hRECT[ "bottom" ], hRECT[ "right" ] + + ? "in HASH" + hRECT := hb_hash() + hRECT[ "left" ] := 300 + hRECT[ "top" ] := 350 + hRECT[ "right" ] := 650 + hRECT[ "bottom" ] := 450 + ? wapi_DrawText( hDC, "4TEST", hRECT ) + + ? wapi_EndPage( hDC ) + ? wapi_EndDoc( hDC ) + + hDC := NIL + hOBJECT := NIL + + RETURN diff --git a/harbour/contrib/hbwin/wapi_wingdi.c b/harbour/contrib/hbwin/wapi_wingdi.c index e097925c10..fbbe2d02d8 100644 --- a/harbour/contrib/hbwin/wapi_wingdi.c +++ b/harbour/contrib/hbwin/wapi_wingdi.c @@ -79,34 +79,36 @@ POINT * hbwapi_par_POINT( POINT * p, int iParam, HB_BOOL bMandatory ) memset( p, 0, sizeof( POINT ) ); - if( HB_IS_HASH( pStru ) ) + if( pStru && HB_IS_HASH( pStru ) ) { p->x = ( LONG ) hb_itemGetNL( hb_hashGetCItemPtr( pStru, "x" ) ); p->y = ( LONG ) hb_itemGetNL( hb_hashGetCItemPtr( pStru, "y" ) ); return p; } - else if( HB_IS_ARRAY( pStru ) && hb_arrayLen( pStru ) >= 2 ) + else if( pStru && HB_IS_ARRAY( pStru ) && hb_arrayLen( pStru ) >= 2 ) { p->x = ( LONG ) hb_arrayGetNL( pStru, 1 ); p->y = ( LONG ) hb_arrayGetNL( pStru, 2 ); return p; } - else - return bMandatory ? p : NULL; + else if( bMandatory ) + return p; + + return NULL; } void hbwapi_stor_POINT( POINT * p, int iParam ) { PHB_ITEM pStru = hb_param( iParam, HB_IT_ANY ); - if( HB_IS_HASH( pStru ) ) + if( pStru && HB_IS_HASH( pStru ) ) { s_hb_hashSetCItemNL( pStru, "x", p->x ); s_hb_hashSetCItemNL( pStru, "y", p->y ); } - else if( HB_IS_ARRAY( pStru ) && hb_arrayLen( pStru ) >= 2 ) + else if( pStru && HB_IS_ARRAY( pStru ) && hb_arrayLen( pStru ) >= 2 ) { hb_arraySetNL( pStru, 1, p->x ); hb_arraySetNL( pStru, 2, p->y ); @@ -119,7 +121,7 @@ RECT * hbwapi_par_RECT( RECT * p, int iParam, HB_BOOL bMandatory ) memset( p, 0, sizeof( RECT ) ); - if( HB_IS_HASH( pStru ) ) + if( pStru && HB_IS_HASH( pStru ) ) { p->left = ( LONG ) hb_itemGetNL( hb_hashGetCItemPtr( pStru, "left" ) ); p->top = ( LONG ) hb_itemGetNL( hb_hashGetCItemPtr( pStru, "top" ) ); @@ -128,7 +130,7 @@ RECT * hbwapi_par_RECT( RECT * p, int iParam, HB_BOOL bMandatory ) return p; } - else if( HB_IS_ARRAY( pStru ) && hb_arrayLen( pStru ) >= 4 ) + else if( pStru && HB_IS_ARRAY( pStru ) && hb_arrayLen( pStru ) >= 4 ) { p->left = ( LONG ) hb_arrayGetNL( pStru, 1 ); p->top = ( LONG ) hb_arrayGetNL( pStru, 2 ); @@ -137,22 +139,24 @@ RECT * hbwapi_par_RECT( RECT * p, int iParam, HB_BOOL bMandatory ) return p; } - else - return bMandatory ? p : NULL; + else if( bMandatory ) + return p; + + return NULL; } void hbwapi_stor_RECT( RECT * p, int iParam ) { PHB_ITEM pStru = hb_param( iParam, HB_IT_ANY ); - if( HB_IS_HASH( pStru ) ) + if( pStru && HB_IS_HASH( pStru ) ) { s_hb_hashSetCItemNL( pStru, "left" , p->left ); s_hb_hashSetCItemNL( pStru, "top" , p->top ); s_hb_hashSetCItemNL( pStru, "right" , p->right ); s_hb_hashSetCItemNL( pStru, "bottom", p->bottom ); } - else if( HB_IS_ARRAY( pStru ) && hb_arrayLen( pStru ) >= 4 ) + else if( pStru && HB_IS_ARRAY( pStru ) && hb_arrayLen( pStru ) >= 4 ) { hb_arraySetNL( pStru, 1, p->left ); hb_arraySetNL( pStru, 2, p->top ); @@ -169,7 +173,7 @@ DEVMODE * hbwapi_par_DEVMODE( DEVMODE * p, int iParam, HB_BOOL bMandatory ) p->dmSize = sizeof( DEVMODE ); - if( HB_IS_HASH( pStru ) ) + if( pStru && HB_IS_HASH( pStru ) ) { p->dmOrientation = ( short ) hb_itemGetNI( hb_hashGetCItemPtr( pStru, "dmOrientation" ) ); p->dmPaperSize = ( short ) hb_itemGetNI( hb_hashGetCItemPtr( pStru, "dmPaperSize" ) ); @@ -193,15 +197,17 @@ DEVMODE * hbwapi_par_DEVMODE( DEVMODE * p, int iParam, HB_BOOL bMandatory ) return p; } - else - return bMandatory ? p : NULL; + else if( bMandatory ) + return p; + + return NULL; } void hbwapi_stor_DEVMODE( DEVMODE * p, int iParam ) { PHB_ITEM pStru = hb_param( iParam, HB_IT_ANY ); - if( HB_IS_HASH( pStru ) ) + if( pStru && HB_IS_HASH( pStru ) ) { s_hb_hashSetCItemNL( pStru, "dmOrientation" , p->dmOrientation ); s_hb_hashSetCItemNL( pStru, "dmPaperSize" , p->dmPaperSize ); @@ -215,6 +221,54 @@ void hbwapi_stor_DEVMODE( DEVMODE * p, int iParam ) } } +DOCINFO * hbwapi_par_DOCINFO( DOCINFO * p, int iParam, HB_BOOL bMandatory, void *** ph ) +{ + PHB_ITEM pStru = hb_param( iParam, HB_IT_ANY ); + void ** h = ( void ** ) hb_xgrabz( 3 * sizeof( void * ) ); + + *ph = h; + + memset( p, 0, sizeof( DOCINFO ) ); + + p->cbSize = sizeof( DOCINFO ); + + if( pStru && HB_IS_HASH( pStru ) ) + { + p->lpszDocName = HB_ITEMGETSTR( hb_hashGetCItemPtr( pStru, "lpszDocName" ), &h[ 0 ], NULL ); + p->lpszOutput = HB_ITEMGETSTR( hb_hashGetCItemPtr( pStru, "lpszOutput" ), &h[ 1 ], NULL ); + p->lpszDatatype = HB_ITEMGETSTR( hb_hashGetCItemPtr( pStru, "lpszDatatype" ), &h[ 2 ], NULL ); + p->fwType = ( DWORD ) hb_itemGetNL( hb_hashGetCItemPtr( pStru, "fwType" ) ); + + return p; + } + else if( pStru && HB_IS_ARRAY( pStru ) && hb_arrayLen( pStru ) >= 4 ) + { + p->lpszDocName = HB_ARRAYGETSTR( pStru, 1, &h[ 0 ], NULL ); /* DEF? */ + p->lpszOutput = HB_ARRAYGETSTR( pStru, 2, &h[ 1 ], NULL ); + p->lpszDatatype = HB_ARRAYGETSTR( pStru, 3, &h[ 2 ], NULL ); + p->fwType = ( DWORD ) hb_arrayGetNL( pStru, 4 ); + + return p; + } + else if( bMandatory ) + return p; + + hb_xfree( h ); + *ph = NULL; + + return NULL; +} + +void hbwapi_strfree_DOCINFO( void ** h ) +{ + if( h ) + { + int i; + for( i = 0; i < 3; ++i ) + hb_strfree( h[ i ] ); + } +} + #if ! defined( HB_OS_WIN_CE ) HB_FUNC( WAPI_CREATEDC ) @@ -248,31 +302,15 @@ HB_FUNC( WAPI_RESETDC ) HB_FUNC( WAPI_STARTDOC ) { HDC hDC = hbwapi_par_HDC( 1 ); - /* TODO: Use hash */ - PHB_ITEM pDOCINFO = hb_param( 2, HB_IT_ARRAY ); - - if( hDC && pDOCINFO && hb_arrayLen( pDOCINFO ) >= 4 ) - { - DOCINFO di; - - void * hDocName; - void * hOutput; - void * hDatatype; - - di.cbSize = sizeof( DOCINFO ); - di.lpszDocName = HB_ARRAYGETSTR( pDOCINFO, 1, &hDocName , NULL ); /* DEF? */ - di.lpszOutput = HB_ARRAYGETSTR( pDOCINFO, 2, &hOutput , NULL ); - di.lpszDatatype = HB_ARRAYGETSTR( pDOCINFO, 3, &hDatatype, NULL ); - di.fwType = ( DWORD ) hb_arrayGetNL( pDOCINFO, 4 ); + void ** hDOCINFO = NULL; + DOCINFO di; + if( hDC && hbwapi_par_DOCINFO( &di, 2, HB_FALSE, &hDOCINFO ) ) hb_retni( StartDoc( hDC, &di ) ); - - hb_strfree( hDocName ); - hb_strfree( hOutput ); - hb_strfree( hDatatype ); - } else hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); + + hbwapi_strfree_DOCINFO( hDOCINFO ); } HB_FUNC( WAPI_ENDDOC ) @@ -512,9 +550,9 @@ HB_FUNC( WAPI_SELECTOBJECT ) HB_BOOL bRegion = HB_FALSE; HGDIOBJ h; - if( ( h = hbwapi_par_HPEN( 2 ) ) != NULL ); - else if( ( h = hbwapi_par_HBRUSH( 2 ) ) != NULL ); - else if( ( h = hbwapi_par_HFONT( 2 ) ) != NULL ); + if( ( h = hbwapi_par_HPEN( 2 ) ) != NULL ) {} + else if( ( h = hbwapi_par_HBRUSH( 2 ) ) != NULL ) {} + else if( ( h = hbwapi_par_HFONT( 2 ) ) != NULL ) {} /* TODO: Add BITMAP, REGION */ else h = NULL;