diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 4a0889d906..1fa2ad047b 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,24 @@ 2002-12-01 23:12 UTC+0100 Foo Bar */ +2004-01-27 16:10 UTC+0100 Ryszard Glab + * source/compiler/harbour.c + * the compiler generates module name inside + '(_INITSTATICS)' function if -B option is used + + * source/vm/hvm.c + * fixed hb_vmStaticName, hb_dbg_vmVarSGet, + hb_dbg_varSSet to use the static variables frame + + * source/debug/dbgtmenu.prg + * source/debug/dbgtmitm.prg + * source/debug/debugger.prg + * fixed parsing of : in watchpoint + expressions + * fixed monitoring of static variables - the + debugger displays now static variables defined + in the current debugged prg file + 2004-01-26 19:30 UTC+0100 Ryszard Glab * include/hbextern.ch * tests/debugtst.prg diff --git a/harbour/source/compiler/harbour.c b/harbour/source/compiler/harbour.c index b7a20175e5..112322623e 100644 --- a/harbour/source/compiler/harbour.c +++ b/harbour/source/compiler/harbour.c @@ -3744,6 +3744,18 @@ void hb_compStaticDefStart( void ) hb_compGenPCodeN( pBuffer, 5, 0 ); hb_compGenPCode3( HB_P_SFRAME, 0, 0, ( BOOL ) 0 ); /* frame for statics variables */ + + if( hb_comp_bDebugInfo ) + { + BYTE * pBuffer; + int iFileLen = strlen( hb_comp_files.pLast->szFileName ); + + pBuffer = ( BYTE * ) hb_xgrab( 2 + iFileLen ); + pBuffer[0] = HB_P_MODULENAME; + memcpy( ( BYTE * ) ( &( pBuffer[1] ) ), ( BYTE * ) hb_comp_files.pLast->szFileName, iFileLen+1 ); + hb_compGenPCodeN( pBuffer, 2 + iFileLen, 0 ); + hb_xfree( pBuffer ); + } } else { diff --git a/harbour/source/debug/dbgtmenu.prg b/harbour/source/debug/dbgtmenu.prg index ba61dc260d..ed41167a39 100644 --- a/harbour/source/debug/dbgtmenu.prg +++ b/harbour/source/debug/dbgtmenu.prg @@ -267,12 +267,19 @@ return 0 METHOD GetItemByIdent( uIdent ) CLASS TDbMenu - local n + local n, oItem for n := 1 to Len( ::aItems ) - if VALTYPE(::aItems[ n ]:Ident) == VALTYPE(uIdent) .AND.; - ::aItems[n]:Ident == uIdent - return ::aItems[ n ] + IF( VALTYPE(::aItems[n]:bAction) == 'O' ) + oItem := ::aItems[n]:bAction:GetItemByIdent( uIdent ) + IF( oItem != NIL ) + RETURN oItem + ENDIF + ELSE + if VALTYPE(::aItems[ n ]:Ident) == VALTYPE(uIdent) .AND.; + ::aItems[n]:Ident == uIdent + return ::aItems[ n ] + ENDIF endif next diff --git a/harbour/source/debug/dbgtmitm.prg b/harbour/source/debug/dbgtmitm.prg index c831cc6053..1803604a85 100644 --- a/harbour/source/debug/dbgtmitm.prg +++ b/harbour/source/debug/dbgtmitm.prg @@ -65,19 +65,23 @@ CLASS TDbMenuItem DATA lChecked DATA Ident - METHOD New( cPrompt, bAction, lChecked ) + ACCESS Checked() INLINE ::lChecked + ASSIGN Checked(lOnOff) INLINE ::lChecked:=lOnOff + + METHOD New( cPrompt, bAction, lChecked, xIdent ) METHOD Display( cClrText, cClrHotKey ) METHOD Toggle() INLINE ::lChecked := ! ::lChecked ENDCLASS -METHOD New( cPrompt, bAction, lChecked, nIdent ) CLASS TDbMenuItem +METHOD New( cPrompt, bAction, lChecked, xIdent ) CLASS TDbMenuItem DEFAULT lChecked TO .f. ::cPrompt := cPrompt ::bAction := bAction ::lChecked := lChecked + ::Ident := xIdent return Self diff --git a/harbour/source/debug/debugger.prg b/harbour/source/debug/debugger.prg index 718702b34a..f4c26b0eab 100644 --- a/harbour/source/debug/debugger.prg +++ b/harbour/source/debug/debugger.prg @@ -134,21 +134,20 @@ procedure __dbgEntry( nMode, uParam1, uParam2, uParam3 ) // debugger entry poin local cProcName local nVarIndex, cVarName - local nAt + local nAt, nSFrame LOCAL aTrace, uValue, lSuccess, nLen - IF( s_lExit ) - RETURN - ENDIF - - IF( s_oDebugger == NIL ) - s_oDebugger := TDebugger():New() + + IF( __MVSCOPE( "__DBGSTATICS" ) != HB_MV_PUBLIC ) public __DbgStatics __DbgStatics := {} ENDIF do case case nMode == HB_DBG_SHOWLINE + IF( s_lExit ) + RETURN + ENDIF IF( s_oDebugger:lTracepoints ) nLen := LEN(s_oDebugger:aTrace) FOR nAt:=1 TO nLen @@ -225,9 +224,19 @@ procedure __dbgEntry( nMode, uParam1, uParam2, uParam3 ) // debugger entry poin s_oDebugger:Activate() endif - case nMode == HB_DBG_MODULENAME // called from hvm.c hb_vmModuleName() + case nMode == HB_DBG_MODULENAME // add a call to the stack but don't try to show the code yet cProcName := ProcName( 1 ) + + if cProcName == "(_INITSTATICS)" + //module wide static variable + AADD( __dbgStatics, { uParam1, {} } ) + return // We can not use s_oDebugger yet, so we return + endif + + IF( s_oDebugger == NIL ) + s_oDebugger := TDebugger():New() + ENDIF if cProcName == "__EVAL" .OR. cProcName == "EVAL" s_oDebugger:lCodeblock := .T. ELSE @@ -236,7 +245,6 @@ procedure __dbgEntry( nMode, uParam1, uParam2, uParam3 ) // debugger entry poin ENDIF endif s_oDebugger:StackProc( uParam1, hb_dbg_ProcLevel()-1 ) -// s_oDebugger:LoadVars() case nMode == HB_DBG_LOCALNAME cProcName := IIF(s_oDebugger:lCodeblock, s_oDebugger:aCallStack[1][CSTACK_FUNCTION], ProcName( 1 )) @@ -252,38 +260,36 @@ procedure __dbgEntry( nMode, uParam1, uParam2, uParam3 ) // debugger entry poin else AAdd( s_oDebugger:aVars, ATAIL( s_oDebugger:aCallStack[ 1 ][ CSTACK_LOCALS ] ) ) endif - if s_oDebugger:oBrwVars != nil - s_oDebugger:oBrwVars:RefreshAll() - endif +// if s_oDebugger:oBrwVars != nil +// s_oDebugger:oBrwVars:RefreshAll() +// endif endif case nMode == HB_DBG_STATICNAME - nVarIndex := uParam1 - cVarName := uParam2 + nSFrame := uParam1 + nVarIndex := uParam2 + cVarName := uParam3 cProcName := ProcName( 1 ) if cProcName == "(_INITSTATICS)" - if AScan( __DbgStatics, { | a | a[ 1 ] == nVarIndex } ) == 0 - AAdd( __DbgStatics, { nVarIndex, { cVarName } } ) - else - AAdd( ATail( __DbgStatics )[ 2 ], cVarName ) - endif + //module wide static variable + AAdd( ATAIL(__DbgStatics)[2], { cVarName, nVarIndex, "Static",, nSFrame } ) return // We can not use s_oDebugger yet, so we return endif - IF Len( s_oDebugger:aCallStack )>0 .AND. valtype( s_oDebugger:aCallStack[ 1, CSTACK_STATICS ])=='A' - AAdd( s_oDebugger:aCallStack[ 1 ][ CSTACK_STATICS ], { cVarName, nVarIndex, "Static" } ) - endif +// IF Len( s_oDebugger:aCallStack )>0 .AND. valtype( s_oDebugger:aCallStack[ 1, CSTACK_STATICS ])=='A' + AAdd( s_oDebugger:aCallStack[ 1 ][ CSTACK_STATICS ], { cVarName, nVarIndex, "Static",, nSFrame } ) +// endif if s_oDebugger:lShowStatics if ( nAt := AScan( s_oDebugger:aVars,; // Is there another var with this name ? - { | aVar | aVar[ 1 ] == cVarName } ) ) != 0 - s_oDebugger:aVars[ nAt ] := { cVarName, nVarIndex, "Static" } + { | aVar | aVar[ VAR_NAME ] == cVarName } ) ) != 0 + s_oDebugger:aVars[ nAt ] := ATAIL( s_oDebugger:aCallStack[ 1 ][ CSTACK_STATICS ] ) else - AAdd( s_oDebugger:aVars, { cVarName, nVarIndex, "Static" } ) - endif - if s_oDebugger:oBrwVars != nil - s_oDebugger:oBrwVars:RefreshAll() + AAdd( s_oDebugger:aVars, ATAIL( s_oDebugger:aCallStack[ 1 ][ CSTACK_STATICS ] ) ) endif +// if s_oDebugger:oBrwVars != nil +// s_oDebugger:oBrwVars:RefreshAll() +// endif endif case nMode == HB_DBG_ENDPROC // called from hvm.c hb_vmDebuggerEndProc() @@ -294,7 +300,6 @@ procedure __dbgEntry( nMode, uParam1, uParam2, uParam3 ) // debugger entry poin s_oDebugger:lCodeblock := .F. endif s_oDebugger:EndProc() -// s_oDebugger:LoadVars() endcase @@ -961,22 +966,10 @@ LOCAL cProc IF( aVar[ VAR_TYPE ] = "L" ) nProcLevel := hb_dbg_procLevel() - aVar[ VAR_LEVEL ] cProc := aVar[ VAR_FUNCNAME ] -/* - IF( cProc = '(b)' ) - //get local var defined in a codeblock - DO WHILE !((cProc:=ProcName( nProcLevel )) == "__EVAL" .OR. cProc == "EVAL" ) - nProcLevel++ - ENDDO - ELSE - DO WHILE( !((uValue:=ProcName( nProcLevel )) == cProc) ) - nProcLevel++ - ENDDO - ENDIF -*/ uValue := hb_dbg_vmVarLGet( nProcLevel, aVar[ VAR_POS ] ) ELSEIF( aVar[ VAR_TYPE ] = "S" ) - uValue := hb_dbg_vmVarSGet( aVar[ VAR_POS ] ) + uValue := hb_dbg_vmVarSGet( aVar[VAR_LEVEL], aVar[ VAR_POS ] ) ELSE //Public or Private @@ -993,22 +986,10 @@ LOCAL cProc IF( aVar[ VAR_TYPE ] = "L" ) nProcLevel := hb_dbg_procLevel() - aVar[VAR_LEVEL] //skip debugger stack cProc := aVar[ VAR_FUNCNAME ] -/* - IF( cProc = '(b)' ) - //get local var defined in a codeblock - DO WHILE !((cProc:=ProcName( nProcLevel )) == "__EVAL" .OR. cProc == "EVAL" ) - nProcLevel++ - ENDDO - ELSE - DO WHILE( !(ProcName( nProcLevel ) == cProc) ) - nProcLevel++ - ENDDO - ENDIF -*/ hb_dbg_vmVarLSet( nProcLevel, aVar[ VAR_POS ], uValue ) ELSEIF( aVar[ VAR_TYPE ] = "S" ) - hb_dbg_vmVarSSet( aVar[ VAR_POS ], uValue ) + hb_dbg_vmVarSSet( aVar[VAR_LEVEL], aVar[ VAR_POS ], uValue ) ELSE //Public or Private @@ -1028,7 +1009,7 @@ METHOD EditVar( nVar ) CLASS TDebugger local aArray local cVarStr - uVarValue := ::VarGetValue( ::aVar[ nVar ] ) + uVarValue := ::VarGetValue( ::aVars[ nVar ] ) do case case ValType( uVarValue ) == "A" @@ -1056,7 +1037,7 @@ METHOD EditVar( nVar ) CLASS TDebugger __DbgObject( uVarValue, cVarName ) otherwise - ::VarSetValue( ::aVar[ nVar ], &cVarStr ) + ::VarSetValue( ::aVars[ nVar ], &cVarStr ) endcase endif @@ -1469,7 +1450,8 @@ METHOD LoadVars() CLASS TDebugger // updates monitored variables local nCount, n, m, xValue, cName local cStaticName, nStaticIndex, nStaticsBase - + LOCAL aVars + ::aVars := {} if ::lShowPublics @@ -1492,22 +1474,32 @@ METHOD LoadVars() CLASS TDebugger // updates monitored variables if ::lShowStatics if Type( "__DbgStatics" ) == "A" - for n := 1 to Len( __DbgStatics ) - for m := 1 to Len( __DbgStatics[ n ][ 2 ] ) - cStaticName := __DbgStatics[ n ][ 2 ][ m ] - nStaticIndex := __DbgStatics[ n ][ 1 ] + m - AAdd( ::aVars, { cStaticName, nStaticIndex, "Static" } ) + cName := ::aCallStack[ ::oBrwStack:Cargo ][ CSTACK_MODULE ] + n := ASCAN( __dbgStatics, {|a| a[1]==cName} ) + IF( n > 0 ) + aVars := __DbgStatics[ n ][ 2 ] + for m := 1 to Len( aVars ) + AAdd( ::aVars, aVars[ m ] ) next - next - for n := 1 to Len( ::aCallStack[ ::oBrwStack:Cargo ][ CSTACK_STATICS ] ) - AAdd( ::aVars, ::aCallStack[ ::oBrwStack:Cargo ][ CSTACK_STATICS ][ n ] ) + ENDIF + aVars := ::aCallStack[ ::oBrwStack:Cargo ][ CSTACK_STATICS ] + for n := 1 to Len( aVars ) + AAdd( ::aVars, aVars[ n ] ) next endif endif if ::lShowLocals - for n := 1 to Len( ::aCallStack[ ::oBrwStack:Cargo ][ CSTACK_LOCALS ] ) - AAdd( ::aVars, ::aCallStack[ ::oBrwStack:Cargo ][ CSTACK_LOCALS ][ n ] ) + aVars := ::aCallStack[ ::oBrwStack:Cargo ][ CSTACK_LOCALS ] + for n := 1 to Len( aVars ) + cName := aVars[ n ][ VAR_NAME ] + m := AScan( ::aVars,; // Is there another var with this name ? + { | aVar | aVar[ VAR_NAME ] == cName .AND. aVar[VAR_TYPE]=='S'} ) + IF( m > 0 ) + ::aVars[ m ] := aVars[ n ] + ELSE + AAdd( ::aVars, aVars[ n ] ) + ENDIF next endif @@ -1738,13 +1730,13 @@ LOCAL cFileName := ::InputBox( "Please enter the filename", Space( 255 ) ) LOCAL cPrgName cFileName:= ALLTRIM( cFileName ) - if (cFileName != ::cPrgName .OR. valtype(::cPrgName)=='U') + if !EMPTY(cFileName) .AND. (cFileName != ::cPrgName .OR. valtype(::cPrgName)=='U') if ! File( cFileName ) .and. ! Empty( ::cPathForFiles ) cFileName := ::LocatePrgPath( cFileName ) endif ::cPrgName := cFileName - ::lppo := RAT(".PPO", UPPER(cFilenAME)) > 0 - ::lPulldown:GetItemByIdent( "PPO" ):lChecked := ::lppo + ::lppo := RAT(".PPO", UPPER(cFileName)) > 0 + ::oPulldown:GetItemByIdent( "PPO" ):Checked := ::lppo ::oBrwText := nil ::oBrwText := TBrwText():New( ::oWndCode:nTop + 1, ::oWndCode:nLeft + 1,; ::oWndCode:nBottom - 1, ::oWndCode:nRight - 1, cFileName,; @@ -2204,8 +2196,8 @@ METHOD Static() CLASS TDebugger ::lShowStatics := ! ::lShowStatics + ::LoadVars() if ::lShowPublics .or. ::lShowPrivates .or. ::lShowStatics .or. ::lShowLocals - ::LoadVars() ::ShowVars() else ::HideVars() @@ -2783,8 +2775,8 @@ return nil STATIC FUNCTION GetWatchValue( aWatch, plSuccess ) LOCAL aVars, i, j -LOCAL nLen -LOCAL cVar, nPos, cProc +LOCAL nLen, aLocVars +LOCAL cVar, nPos, cName LOCAL xVal LOCAL oErr LOCAL bEBlock @@ -2799,37 +2791,29 @@ LOCAL bEBlock FOR i:=1 TO nLen cVar := aWatch[ i + WP_BLOCK ] //search local variables in current procedure - nPos := ASCAN( s_oDebugger:aCallStack[1][CSTACK_LOCALS], {|a| a[VAR_NAME]==cVar} ) + aLocVars := s_oDebugger:aCallStack[1][CSTACK_LOCALS] + nPos := ASCAN( aLocVars, {|a| a[VAR_NAME]==cVar} ) IF( nPos > 0 ) - j :=hb_dbg_ProcLevel() - s_oDebugger:aCallStack[1][CSTACK_LOCALS][ nPos ][ VAR_LEVEL ] -/* - cProc := s_oDebugger:aCallStack[1][CSTACK_LOCALS][nPos][VAR_FUNCNAME] - IF( cProc = '(b)' ) - //get local var defined in a codeblock - DO WHILE !((cProc:=ProcName( j )) == "__EVAL" .OR. cProc == "EVAL" ) - j++ - ENDDO - ELSE - DO WHILE( ProcName( j ) != cProc ) - j++ - ENDDO - ENDIF -*/ - aVars[i] := hb_dbg_vmVarLGet( j, s_oDebugger:aCallStack[1][CSTACK_LOCALS][ nPos ][ VAR_POS ] ) + j :=hb_dbg_ProcLevel() - aLocVars[ nPos ][ VAR_LEVEL ] + aVars[i] := hb_dbg_vmVarLGet( j, aLocVars[ nPos ][ VAR_POS ] ) ELSE //search local statics - nPos := ASCAN( s_oDebugger:aCallStack[1][CSTACK_STATICS], {|a| a[VAR_NAME]==cVar} ) + aLocVars := s_oDebugger:aCallStack[1][CSTACK_STATICS] + nPos := ASCAN( aLocVars, {|a| a[VAR_NAME]==cVar} ) IF( nPos > 0 ) - aVars[i] := hb_dbg_vmVarSGet( s_oDebugger:aCallStack[1][CSTACK_STATICS][ nPos ][ 2 ] ) + aVars[i] := hb_dbg_vmVarSGet( aLocVars[ nPos ][VAR_LEVEL], aLocVars[ nPos ][VAR_POS] ) ELSE //search global statics - FOR j:=1 TO LEN(__dbgStatics) - nPos := ASCAN( __dbgStatics[j][ 2 ], {|c| c==cVar} ) + cName := s_oDebugger:aCallStack[1][CSTACK_MODULE] + nPos := ASCAN( __dbgStatics, {|a| a[1]==cName} ) + IF( nPos > 0 ) + aLocVars := __dbgStatics[nPos][ 2 ] + nPos := ASCAN( aLocVars, {|a| a[VAR_NAME]==cVar} ) IF( nPos > 0 ) - aVars[i] :=hb_dbg_vmVarSGet(__dbgStatics[j][1]+nPos ) + aVars[i] :=hb_dbg_vmVarSGet( aLocVars[ nPos ][VAR_LEVEL], aLocVars[ nPos ][VAR_POS] ) EXIT ENDIF - NEXT + ENDIF IF( nPos == 0 ) aVars[i] := &cVar ENDIF @@ -2927,6 +2911,12 @@ LOCAL cRet i++ ENDDO + ELSEIF( c = ':' ) //skip send operator + i++ + DO WHILE( i<=nLen .AND. IsIdentChar(SUBSTR(cExpr,i,1)) ) + i++ + ENDDO + ELSEIF( c = "'" .OR. c = '"' ) //STRING i++ DO WHILE( i<=nLen .AND. SUBSTR(cExpr,i,1)!=c ) diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index 64846bb3c5..3037c3be4d 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -3767,13 +3767,11 @@ static void hb_vmStaticName( BYTE bIsGlobal, USHORT uiStatic, char * szStaticNam hb_vmPushSymbol( hb_dynsymFind( "__DBGENTRY" )->pSymbol ); hb_vmPushNil(); hb_vmPushLongConst( HB_DBG_STATICNAME ); - if( bIsGlobal ) - hb_vmPushLongConst( hb_arrayLen( &s_aStatics ) - s_uiStatics ); - else - hb_vmPushLongConst( hb_stack.iStatics + uiStatic ); + hb_vmPushLongConst( hb_stack.iStatics ); /* current static frame */ + hb_vmPushLongConst( uiStatic ); /* variable index */ hb_vmPushString( szStaticName, strlen( szStaticName ) ); s_bDebuggerIsWorking = TRUE; - hb_vmDo( 3 ); + hb_vmDo( 4 ); s_bDebuggerIsWorking = FALSE; s_bDebugShowLines = TRUE; } @@ -5066,10 +5064,7 @@ HB_FUNC( HB_DBG_VMVARSLEN ) * $End$ */ HB_FUNC( HB_DBG_VMVARSGET ) { - /* hb_itemReturn( s_aStatics.item.asArray.value->pItems + - hb_stack.iStatics + hb_parni( 1 ) - 1 ); */ - - hb_itemReturn( s_aStatics.item.asArray.value->pItems + hb_parni( 1 ) - 1 ); + hb_itemReturn( s_aStatics.item.asArray.value->pItems + hb_parni(1) + hb_parni(2) - 1 ); } /* $Doc$ @@ -5078,8 +5073,8 @@ HB_FUNC( HB_DBG_VMVARSGET ) * $End$ */ HB_FUNC( HB_DBG_VMVARSSET ) { - hb_itemCopy( s_aStatics.item.asArray.value->pItems + hb_parni( 1 ) - 1, - * ( hb_stack.pBase + 3 ) ); + hb_itemCopy( s_aStatics.item.asArray.value->pItems + hb_parni(1) + hb_parni(2) - 1, + hb_itemParamPtr( 3, HB_IT_ANY ) ); } HB_FUNC( HB_DBG_PROCLEVEL )