diff --git a/ChangeLog.txt b/ChangeLog.txt index b17cd05eaa..4b3800fa1d 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -10,6 +10,31 @@ * Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment */ +2013-07-03 12:14 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + * include/hbapidbg.h + * src/debug/dbgentry.c + * src/debug/debugger.prg + + added new C function hb_dbgGetModuleName() - it returns module name + used to register module in HVM. In current version it only strips + path part though in the future it may use some more advanced code + which allow to debug modules with the same name but different paths + in single application and such extension will be local to core debug + code if upper level debugger uses hb_dbgGetModuleName() + + added new PRG function __DBGGETMODULENAME() - it's wrapper to + hb_dbgGetModuleName() + + added new PRG function __DBGMODULEMATCH() + ! use __DBGMODULEMATCH() instead of hb_FileMatch() and strip_path() + ! eliminated strip_path() from PRG code and use hb_dbgGetModuleName() + in C code in places where it's necessary + ! replaced few strcmp() used to compare module names with + FILENAME_EQUAL() + ; above modification may fix few potential problem with breakpoints + in debugger on some platforms if user uses different paths for + debugger and compilers. + ! eliminated hack with memvar/field name copy in watch points, + it also fixes memory leak when fields are used in watch points. + % replaced few DO CASE with SWITCH + 2013-06-21 14:58 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * contrib/gtqtc/gtqtc.h * contrib/gtqtc/gtqtc1.cpp diff --git a/include/hbapidbg.h b/include/hbapidbg.h index 98190d5fc7..ceaa79dc46 100644 --- a/include/hbapidbg.h +++ b/include/hbapidbg.h @@ -67,7 +67,8 @@ extern HB_EXPORT PHB_ITEM hb_dbg_vmVarGGet( int nGlobal, int nOffset ); /* internal debugger function */ extern HB_EXPORT void hb_dbgEntry( int nMode, int nLine, const char * szName, int nIndex, PHB_ITEM pFrame ); -extern HB_EXPORT void hb_dbgAddBreak( void * handle, const char * cModule, int nLine, const char * szFunction ); +extern HB_EXPORT const char * hb_dbgGetModuleName( void * handle, const char * szName ); +extern HB_EXPORT void hb_dbgAddBreak( void * handle, const char * szModule, int nLine, const char * szFunction ); extern HB_EXPORT void hb_dbgAddWatch( void * handle, const char * szExpr, HB_BOOL bTrace ); extern HB_EXPORT void hb_dbgDelBreak( void * handle, int nBreak ); extern HB_EXPORT void hb_dbgDelWatch( void * handle, int nWatch ); diff --git a/src/debug/dbgentry.c b/src/debug/dbgentry.c index d5bdfb4d07..3d13a0c569 100644 --- a/src/debug/dbgentry.c +++ b/src/debug/dbgentry.c @@ -103,8 +103,8 @@ typedef struct typedef struct { - char * szName; - char cType; + const char * szName; + char cType; union { int num; @@ -178,6 +178,7 @@ typedef struct HB_BOOL bInitGlobals; HB_BOOL bInitStatics; HB_BOOL bInitLines; + PHB_DYNS pDbgEntry; } HB_DEBUGINFO; static HB_DBGCOMMONINFO s_common = { 0, NULL, NULL }; @@ -206,14 +207,19 @@ static void hb_dbgVarSet( HB_VARINFO * scope, PHB_ITEM xNewValue ); static void hb_dbgActivate( HB_DEBUGINFO * info ) { - PHB_DYNS pDynSym = hb_dynsymFind( "__DBGENTRY" ); - - if( pDynSym && hb_dynsymIsFunction( pDynSym ) ) + if( ! info->pDbgEntry ) + { + info->pDbgEntry = hb_dynsymFind( "__DBGENTRY" ); + if( info->pDbgEntry && ! hb_dynsymIsFunction( info->pDbgEntry ) ) + info->pDbgEntry = NULL; + } + + if( info->pDbgEntry ) { - int i; PHB_ITEM aCallStack = hb_itemArrayNew( info->nCallStackLen ); PHB_ITEM aModules; PHB_ITEM aBreak; + int i; for( i = 0; i < info->nCallStackLen; i++ ) { @@ -241,7 +247,7 @@ static void hb_dbgActivate( HB_DEBUGINFO * info ) aModules = hb_dbgActivateModuleArray(); aBreak = hb_dbgActivateBreakArray( info ); - hb_vmPushDynSym( pDynSym ); + hb_vmPushDynSym( info->pDbgEntry ); hb_vmPushNil(); hb_vmPushLong( HB_DBG_ACTIVATE ); hb_vmPushPointer( info ); @@ -569,6 +575,7 @@ void hb_dbgAddBreak( void * handle, const char * szModule, int nLine, const char HB_DEBUGINFO * info = ( HB_DEBUGINFO * ) handle; HB_BREAKPOINT * pBreak; + szModule = hb_dbgStripModuleName( szModule ); pBreak = ARRAY_ADD( HB_BREAKPOINT, info->aBreak, info->nBreakPoints ); pBreak->szModule = hb_strdup( szModule ); pBreak->nLine = nLine; @@ -613,7 +620,7 @@ static void hb_dbgAddModule( const char * szName ) szModuleName = hb_strndup( szName, iLen ); HB_DBGCOMMON_LOCK(); - if( ! s_common.nModules || strcmp( s_common.aModules[ s_common.nModules - 1 ].szModule, szModuleName ) ) + if( ! s_common.nModules || !FILENAME_EQUAL( s_common.aModules[ s_common.nModules - 1 ].szModule, szModuleName ) ) { HB_MODULEINFO * pModule; @@ -636,8 +643,11 @@ static void hb_dbgAddStack( HB_DEBUGINFO * info, const char * szName, int nProcL { char szBuff[ HB_SYMBOL_NAME_LEN + HB_SYMBOL_NAME_LEN + 5 ]; HB_CALLSTACKINFO * top; - const char * szFunction = strrchr( szName, ':' ); + const char * szFunction; + szName = hb_dbgStripModuleName( szName ); + + szFunction = strrchr( szName, ':' ); if( szFunction ) szFunction++; @@ -662,8 +672,6 @@ static void hb_dbgAddStack( HB_DEBUGINFO * info, const char * szName, int nProcL } } - szName = hb_dbgStripModuleName( szName ); - if( szFunction ) top->szModule = hb_strndup( szName, szFunction - szName - 1 ); else @@ -735,7 +743,7 @@ static void hb_dbgAddStopLines( PHB_ITEM pItem ) { PHB_ITEM pLines = hb_arrayGetItemPtr( s_common.pStopLines, j ); - if( ! strcmp( hb_arrayGetCPtr( pLines, 1 ), szModule ) ) + if( FILENAME_EQUAL( hb_arrayGetCPtr( pLines, 1 ), szModule ) ) { /* Merge stopline info */ HB_ISIZ nOrigMin = hb_arrayGetNS( pLines, 2 ); @@ -797,8 +805,7 @@ static void hb_dbgAddVar( int * nVars, HB_VARINFO ** aVars, const char * szName, HB_VARINFO * var; var = ARRAY_ADD( HB_VARINFO, *aVars, *nVars ); - /* TODO/TOFIX: value should be duplicated here and then released */ - var->szName = ( char * ) szName; + var->szName = szName; var->cType = cType; var->nIndex = nIndex; if( cType == 'S' ) @@ -972,11 +979,6 @@ static PHB_ITEM hb_dbgEval( HB_DEBUGINFO * info, HB_WATCHPOINT * watch ) hb_itemRelease( aVars ); hb_itemRelease( aNewVars ); - for( i = 0; i < watch->nVars; i++ ) - { - if( watch->aScopes[ i ].cType == 'M' ) - hb_xfree( watch->aScopes[ i ].szName ); - } if( watch->nVars ) hb_xfree( watch->aScopes ); } @@ -1061,18 +1063,14 @@ static PHB_ITEM hb_dbgEvalMakeBlock( HB_WATCHPOINT * watch ) c = watch->szExpr[ j ]; } nLen = j - i; - szWord = hb_strndup( watch->szExpr + i, nLen ); i = j; if( c ) { - while( watch->szExpr[ i ] && watch->szExpr[ i ] == ' ' ) + while( watch->szExpr[ i ] == ' ' ) i++; if( watch->szExpr[ i ] == '(' ) - { - hb_xfree( szWord ); continue; - } if( watch->szExpr[ i ] == '-' && watch->szExpr[ i + 1 ] == '>' ) { @@ -1081,11 +1079,10 @@ static PHB_ITEM hb_dbgEvalMakeBlock( HB_WATCHPOINT * watch ) while( ( c = watch->szExpr[ i ] ) != '\0' && IS_IDENT_CHAR( c ) ) i++; - hb_xfree( szWord ); continue; } } - hb_strupr( szWord ); + szWord = hb_strupr( hb_strndup( watch->szExpr + nStart, nLen ) ); i = hb_dbgEvalSubstituteVar( watch, szWord, nStart, nLen ); bAfterId = HB_TRUE; continue; @@ -1213,7 +1210,7 @@ static PHB_ITEM hb_dbgEvalResolve( HB_DEBUGINFO * info, HB_WATCHPOINT * watch ) for( i = 0; i < s_common.nModules; i++ ) { - if( ! strcmp( s_common.aModules[ i ].szModule, top->szModule ) ) + if( FILENAME_EQUAL( s_common.aModules[ i ].szModule, top->szModule ) ) { module = &s_common.aModules[ i ]; break; @@ -1306,7 +1303,7 @@ static PHB_ITEM hb_dbgEvalResolve( HB_DEBUGINFO * info, HB_WATCHPOINT * watch ) } scopes[ i ].cType = 'M'; - scopes[ i ].szName = hb_strdup( name ); + scopes[ i ].szName = hb_dynsymGetSymbol( name )->szName; pItem = hb_dbgVarGet( &scopes[ i ] ); @@ -1383,6 +1380,8 @@ static HB_BOOL hb_dbgIsBreakPoint( HB_DEBUGINFO * info, const char * szModule, i { int i; + /* szModule has stripped path here */ + for( i = 0; i < info->nBreakPoints; i++ ) { HB_BREAKPOINT * point = &info->aBreak[ i ]; @@ -1404,6 +1403,8 @@ HB_BOOL hb_dbgIsValidStopLine( void * handle, const char * szModule, int nLine ) /* HB_DEBUGINFO * info = ( HB_DEBUGINFO * ) handle; */ HB_SYMBOL_UNUSED( handle ); + szModule = hb_dbgStripModuleName( szModule ); + HB_DBGCOMMON_LOCK(); nModules = hb_itemSize( s_common.pStopLines ); for( i = 1; i <= nModules; i++ ) @@ -1426,6 +1427,18 @@ HB_BOOL hb_dbgIsValidStopLine( void * handle, const char * szModule, int nLine ) } +const char * hb_dbgGetModuleName( void * handle, const char * szName ) +{ + /* HB_DEBUGINFO * info = ( HB_DEBUGINFO * ) handle; */ + HB_SYMBOL_UNUSED( handle ); + + if( szName ) + szName = hb_dbgStripModuleName( szName ); + + return szName; +} + + static void hb_dbgQuit( HB_DEBUGINFO * info ) { while( info->nWatchPoints ) @@ -1524,6 +1537,8 @@ void hb_dbgSetToCursor( void * handle, const char * szModule, int nLine ) { HB_DEBUGINFO * info = ( HB_DEBUGINFO * ) handle; + szModule = hb_dbgStripModuleName( szModule ); + info->bToCursor = HB_TRUE; info->szToCursorModule = hb_strdup( szModule ); info->nToCursorLine = nLine; @@ -1771,6 +1786,29 @@ HB_FUNC( __DBGSETWATCH ) hb_dbgSetWatch( ptr, hb_parni( 2 ), hb_parc( 3 ), hb_parl( 4 ) ); } +HB_FUNC( __DBGGETMODULENAME ) +{ + void * ptr = hb_parptr( 1 ); + + if( ptr ) + hb_retc( hb_dbgGetModuleName( ptr, hb_parc( 2 ) ) ); +} + +HB_FUNC( __DBGMODULEMATCH ) +{ + void * ptr = hb_parptr( 1 ); + + if( ptr ) + { + const char * szModule1 = hb_parc( 2 ), + * szModule2 = hb_parc( 3 ); + + hb_retl( szModule1 && szModule2 && + FILENAME_EQUAL( hb_dbgStripModuleName( szModule1 ), + hb_dbgStripModuleName( szModule2 ) ) ); + } +} + HB_FUNC( __DBGSENDMSG ) { hb_dbg_objSendMessage( hb_parnl( 1 ), hb_param( 2, HB_IT_ANY ), diff --git a/src/debug/debugger.prg b/src/debug/debugger.prg index e20029e10b..bf8fdfefb0 100644 --- a/src/debug/debugger.prg +++ b/src/debug/debugger.prg @@ -131,12 +131,8 @@ PROCEDURE __dbgEntry( nMode, uParam1, uParam2, uParam3, uParam4, uParam5 ) LOCAL lStartup - DO CASE - CASE nMode == HB_DBG_GETENTRY - - __dbgSetEntry() - - CASE nMode == HB_DBG_ACTIVATE + SWITCH nMode + CASE HB_DBG_ACTIVATE IF ( lStartup := ( t_oDebugger == NIL ) ) t_oDebugger := HBDebugger():New() @@ -154,8 +150,13 @@ PROCEDURE __dbgEntry( nMode, uParam1, uParam2, uParam3, uParam4, uParam5 ) ENDIF t_oDebugger:lGo := .F. t_oDebugger:Activate() + RETURN - ENDCASE + CASE HB_DBG_GETENTRY + + __dbgSetEntry() + + ENDSWITCH RETURN @@ -268,6 +269,7 @@ CREATE CLASS HBDebugger METHOD FindPrevious() METHOD GetExprValue( xExpr, lValid ) METHOD GetSourceFiles() + METHOD ModuleMatch( cModuleName1, cModuleName2 ) METHOD Global() @@ -564,52 +566,62 @@ METHOD CallStackProcessKey( nKey ) CLASS HBDebugger LOCAL nSkip LOCAL lUpdate := .F. - DO CASE - CASE nKey == K_HOME .OR. nKey == K_CTRL_PGUP .OR. nKey == K_CTRL_HOME + SWITCH nKey + CASE K_HOME + CASE K_CTRL_PGUP + CASE K_CTRL_HOME IF ::oBrwStack:Cargo > 1 ::oBrwStack:GoTop() ::oBrwStack:ForceStable() lUpdate := .T. ENDIF + EXIT - CASE nKey == K_END .OR. nKey == K_CTRL_PGDN .OR. nKey == K_CTRL_END + CASE K_END + CASE K_CTRL_PGDN + CASE K_CTRL_END IF ::oBrwStack:Cargo < Len( ::aProcStack ) ::oBrwStack:GoBottom() ::oBrwStack:ForceStable() lUpdate := .T. ENDIF + EXIT - CASE nKey == K_UP + CASE K_UP IF ::oBrwStack:Cargo > 1 ::oBrwStack:Up() ::oBrwStack:ForceStable() lUpdate := .T. ENDIF + EXIT - CASE nKey == K_DOWN + CASE K_DOWN IF ::oBrwStack:Cargo < Len( ::aProcStack ) ::oBrwStack:Down() ::oBrwStack:ForceStable() lUpdate := .T. ENDIF + EXIT - CASE nKey == K_PGUP + CASE K_PGUP ::oBrwStack:PageUp() ::oBrwStack:ForceStable() lUpdate := .T. + EXIT - CASE nKey == K_PGDN + CASE K_PGDN ::oBrwStack:PageDown() ::oBrwStack:ForceStable() lUpdate := .T. + EXIT - CASE nKey == K_LBUTTONDOWN + CASE K_LBUTTONDOWN IF ( nSkip := MRow() - ::oWndStack:nTop - ::oBrwStack:RowPos ) != 0 IF nSkip > 0 @@ -626,8 +638,9 @@ METHOD CallStackProcessKey( nKey ) CLASS HBDebugger ::oBrwStack:ForceStable() ENDIF lUpdate := .T. + EXIT - ENDCASE + ENDSWITCH IF lUpdate IF ::oWndVars != NIL .AND. ::oWndVars:lVisible @@ -663,15 +676,20 @@ METHOD CodeWindowProcessKey( nKey ) CLASS HBDebugger IF ::oBrwText != NIL - DO CASE - CASE nKey == K_HOME .OR. nKey == K_CTRL_PGUP .OR. nKey == K_CTRL_HOME + SWITCH nKey + CASE K_HOME + CASE K_CTRL_PGUP + CASE K_CTRL_HOME ::oBrwText:GoTop() IF ::oWndCode:lFocused SetCursor( SC_SPECIAL1 ) ENDIF + EXIT - CASE nKey == K_END .OR. nKey == K_CTRL_PGDN .OR. nKey == K_CTRL_END + CASE K_END + CASE K_CTRL_PGDN + CASE K_CTRL_END ::oBrwText:GoBottom() ::oBrwText:nCol := ::oWndCode:nLeft + 1 @@ -680,26 +698,33 @@ METHOD CodeWindowProcessKey( nKey ) CLASS HBDebugger IF ::oWndCode:lFocused SetCursor( SC_SPECIAL1 ) ENDIF + EXIT - CASE nKey == K_LEFT + CASE K_LEFT ::oBrwText:Left() + EXIT - CASE nKey == K_RIGHT + CASE K_RIGHT ::oBrwText:Right() + EXIT - CASE nKey == K_UP + CASE K_UP ::oBrwText:Up() + EXIT - CASE nKey == K_DOWN + CASE K_DOWN ::oBrwText:Down() + EXIT - CASE nKey == K_PGUP + CASE K_PGUP ::oBrwText:PageUp() + EXIT - CASE nKey == K_PGDN + CASE K_PGDN ::oBrwText:PageDown() + EXIT - ENDCASE + ENDSWITCH ENDIF RETURN NIL @@ -872,7 +897,7 @@ METHOD DoCommand( cCommand ) CLASS HBDebugger ELSE cParam1 := ::cPrgName ENDIF - ::ToggleBreakPoint( Val( cParam ), strip_path( cParam1 ) ) + ::ToggleBreakPoint( Val( cParam ), cParam1 ) ELSE ::ToggleBreakPoint() ENDIF @@ -1202,6 +1227,10 @@ METHOD GetSourceFiles() CLASS HBDebugger RETURN __dbgGetSourceFiles( ::pInfo ) +METHOD ModuleMatch( cModuleName1, cModuleName2 ) CLASS HBDebugger + RETURN __dbgModuleMatch( ::pInfo, cModuleName1, cModuleName2 ) + + METHOD Global() CLASS HBDebugger ::lShowGlobals := ! ::lShowGlobals @@ -1537,11 +1566,12 @@ METHOD InputBox( cMsg, uValue, bValid, lEditable ) CLASS HBDebugger DO WHILE ! lExit Inkey( 0 ) - DO CASE - CASE LastKey() == K_ESC + SWITCH LastKey() + CASE K_ESC lExit := .T. + EXIT - CASE LastKey() == K_ENTER + CASE K_ENTER IF cType == "A" IF Len( uValue ) == 0 __dbgAlert( "Array is empty" ) @@ -1562,10 +1592,12 @@ METHOD InputBox( cMsg, uValue, bValid, lEditable ) CLASS HBDebugger ELSE __dbgAlert( "Value cannot be edited" ) ENDIF + EXIT OTHERWISE __dbgAlert( "Value cannot be edited" ) - ENDCASE + + ENDSWITCH ENDDO ENDIF @@ -1736,7 +1768,7 @@ METHOD LoadVars() CLASS HBDebugger // updates monitored variables cName := ::aProcStack[ ::oBrwStack:Cargo ][ CSTACK_MODULE ] FOR n := 1 TO Len( ::aModules ) IF ! ::lShowAllGlobals - IF ! hb_FileMatch( ::aModules[ n ][ MODULE_NAME ], cName ) + IF ! ::ModuleMatch( ::aModules[ n ][ MODULE_NAME ], cName ) LOOP ENDIF ENDIF @@ -1755,7 +1787,7 @@ METHOD LoadVars() CLASS HBDebugger // updates monitored variables IF ::lShowStatics cName := ::aProcStack[ ::oBrwStack:Cargo ][ CSTACK_MODULE ] - n := AScan( ::aModules, {| a | hb_FileMatch( a[ MODULE_NAME ], cName ) } ) + n := AScan( ::aModules, {| a | ::ModuleMatch( a[ MODULE_NAME ], cName ) } ) IF n > 0 aVars := ::aModules[ n ][ MODULE_STATICS ] FOR m := 1 TO Len( aVars ) @@ -2083,7 +2115,7 @@ METHOD RedisplayBreakPoints() CLASS HBDebugger LOCAL n FOR n := 1 TO Len( ::aBreakpoints ) - IF hb_FileMatch( ::aBreakpoints[ n ][ 2 ], strip_path( ::cPrgName ) ) + IF ::ModuleMatch( ::aBreakpoints[ n ][ 2 ], ::cPrgName ) ::oBrwText:ToggleBreakPoint( ::aBreakpoints[ n ][ 1 ], .T. ) ENDIF NEXT @@ -2493,7 +2525,7 @@ METHOD ShowCodeLine( nProc ) CLASS HBDebugger IF ! Empty( cPrgName ) - IF ! hb_FileMatch( strip_path( cPrgName ), strip_path( ::cPrgName ) ) .OR. ; + IF ! ::ModuleMatch( cPrgName, ::cPrgName ) .OR. ; ::oBrwText == NIL IF ! hb_FileExists( cPrgName ) .AND. ! Empty( ::cPathForFiles ) @@ -2728,8 +2760,8 @@ METHOD Step() CLASS HBDebugger METHOD ToCursor() CLASS HBDebugger - IF ::IsValidStopLine( strip_path( ::cPrgName ), ::oBrwText:RowPos ) - __dbgSetToCursor( ::pInfo, strip_path( ::cPrgName ), ::oBrwText:RowPos ) + IF ::IsValidStopLine( ::cPrgName, ::oBrwText:RowPos ) + __dbgSetToCursor( ::pInfo, ::cPrgName, ::oBrwText:RowPos ) ::RestoreAppScreen() ::RestoreAppState() ::Exit() @@ -2751,7 +2783,7 @@ METHOD ToggleBreakPoint( nLine, cFileName ) CLASS HBDebugger ENDIF IF nLine == NIL - cFileName := strip_path( ::cPrgName ) + cFileName := ::cPrgName nLine := ::oBrwText:RowPos ENDIF @@ -2760,18 +2792,18 @@ METHOD ToggleBreakPoint( nLine, cFileName ) CLASS HBDebugger ENDIF nAt := AScan( ::aBreakPoints, {| aBreak | aBreak[ 1 ] == nLine ; - .AND. hb_FileMatch( aBreak[ 2 ], cFileName ) } ) + .AND. ::ModuleMatch( aBreak[ 2 ], cFileName ) } ) IF nAt == 0 AAdd( ::aBreakPoints, { nLine, cFileName } ) // it was nLine __dbgAddBreak( ::pInfo, cFileName, nLine ) - IF hb_FileMatch( cFileName, strip_path( ::cPrgName ) ) + IF ::ModuleMatch( cFileName, ::cPrgName ) ::oBrwText:ToggleBreakPoint( nLine, .T. ) ENDIF ELSE hb_ADel( ::aBreakPoints, nAt, .T. ) __dbgDelBreak( ::pInfo, nAt - 1 ) - IF hb_FileMatch( cFileName, strip_path( ::cPrgName ) ) + IF ::ModuleMatch( cFileName, ::cPrgName ) ::oBrwText:ToggleBreakPoint( nLine, .F. ) ENDIF ENDIF @@ -2816,15 +2848,14 @@ METHOD TracepointAdd( cExpr ) CLASS HBDebugger METHOD VarGetInfo( aVar ) CLASS HBDebugger - LOCAL cType := Left( aVar[ VAR_TYPE ], 1 ) LOCAL uValue := ::VarGetValue( aVar ) - DO CASE - CASE cType == "G" ; RETURN aVar[ VAR_NAME ] + " : " + __dbgValToStr( uValue ) - CASE cType == "L" ; RETURN aVar[ VAR_NAME ] + " : " + __dbgValToStr( uValue ) - CASE cType == "S" ; RETURN aVar[ VAR_NAME ] + " : " + __dbgValToStr( uValue ) - OTHERWISE ; RETURN aVar[ VAR_NAME ] + " <" + aVar[ VAR_TYPE ] + ", " + ValType( uValue ) + ">: " + __dbgValToStr( uValue ) - ENDCASE + SWITCH Left( aVar[ VAR_TYPE ], 1 ) + CASE "G" ; RETURN aVar[ VAR_NAME ] + " : " + __dbgValToStr( uValue ) + CASE "L" ; RETURN aVar[ VAR_NAME ] + " : " + __dbgValToStr( uValue ) + CASE "S" ; RETURN aVar[ VAR_NAME ] + " : " + __dbgValToStr( uValue ) + OTHERWISE; RETURN aVar[ VAR_NAME ] + " <" + aVar[ VAR_TYPE ] + ", " + ValType( uValue ) + ">: " + __dbgValToStr( uValue ) + ENDSWITCH // ; Never reached @@ -2833,14 +2864,12 @@ METHOD VarGetInfo( aVar ) CLASS HBDebugger METHOD VarGetValue( aVar ) CLASS HBDebugger - LOCAL cType := Left( aVar[ VAR_TYPE ], 1 ) - - DO CASE - CASE cType == "G" ; RETURN __dbgVMVarGGet( aVar[ VAR_LEVEL ], aVar[ VAR_POS ] ) - CASE cType == "L" ; RETURN __dbgVMVarLGet( __dbgProcLevel() - aVar[ VAR_LEVEL ], aVar[ VAR_POS ] ) - CASE cType == "S" ; RETURN __dbgVMVarSGet( aVar[ VAR_LEVEL ], aVar[ VAR_POS ] ) - OTHERWISE ; RETURN aVar[ VAR_POS ] // Public or Private - ENDCASE + SWITCH Left( aVar[ VAR_TYPE ], 1 ) + CASE "G" ; RETURN __dbgVMVarGGet( aVar[ VAR_LEVEL ], aVar[ VAR_POS ] ) + CASE "L" ; RETURN __dbgVMVarLGet( __dbgProcLevel() - aVar[ VAR_LEVEL ], aVar[ VAR_POS ] ) + CASE "S" ; RETURN __dbgVMVarSGet( aVar[ VAR_LEVEL ], aVar[ VAR_POS ] ) + OTHERWISE; RETURN aVar[ VAR_POS ] // Public or Private + ENDSWITCH // ; Never reached @@ -2850,24 +2879,23 @@ METHOD VarGetValue( aVar ) CLASS HBDebugger METHOD VarSetValue( aVar, uValue ) CLASS HBDebugger LOCAL nProcLevel - LOCAL cType := Left( aVar[ VAR_TYPE ], 1 ) - IF cType == "G" + SWITCH Left( aVar[ VAR_TYPE ], 1 ) + CASE "G" __dbgVMVarGSet( aVar[ VAR_LEVEL ], aVar[ VAR_POS ], uValue ) - - ELSEIF cType == "L" + EXIT + CASE "L" nProcLevel := __dbgProcLevel() - aVar[ VAR_LEVEL ] // skip debugger stack __dbgVMVarLSet( nProcLevel, aVar[ VAR_POS ], uValue ) - - ELSEIF cType == "S" + EXIT + CASE "S" __dbgVMVarSSet( aVar[ VAR_LEVEL ], aVar[ VAR_POS ], uValue ) - - ELSE + EXIT + OTHERWISE // Public or Private aVar[ VAR_POS ] := uValue &( aVar[ VAR_NAME ] ) := uValue - - ENDIF + ENDSWITCH RETURN Self @@ -3179,32 +3207,38 @@ METHOD WndVarsLButtonDown( nMRow, nMCol ) CLASS HBDebugger STATIC PROCEDURE SetsKeyPressed( nKey, oBrwSets, nSets, oWnd, cCaption, bEdit ) - DO CASE - CASE nKey == K_UP - + SWITCH nKey + CASE K_UP oBrwSets:up() + EXIT - CASE nKey == K_DOWN - + CASE K_DOWN oBrwSets:down() + EXIT - CASE nKey == K_HOME .OR. nKey == K_CTRL_PGUP .OR. nKey == K_CTRL_HOME - + CASE K_HOME + CASE K_CTRL_PGUP + CASE K_CTRL_HOME oBrwSets:goTop() + EXIT - CASE nKey == K_END .OR. nKey == K_CTRL_PGDN .OR. nKey == K_CTRL_END - + CASE K_END + CASE K_CTRL_PGDN + CASE K_CTRL_END oBrwSets:goBottom() + EXIT - CASE nKey == K_PGDN + CASE K_PGDN oBrwSets:pageDown() + EXIT - CASE nKey == K_PGUP + CASE K_PGUP oBrwSets:pageUp() + EXIT - CASE nKey == K_ENTER + CASE K_ENTER IF bEdit != NIL Eval( bEdit ) @@ -3213,8 +3247,9 @@ STATIC PROCEDURE SetsKeyPressed( nKey, oBrwSets, nSets, oWnd, cCaption, bEdit ) IF LastKey() == K_ENTER hb_keyPut( K_DOWN ) ENDIF + EXIT - ENDCASE + ENDSWITCH RefreshVarsS( oBrwSets ) @@ -3282,19 +3317,6 @@ STATIC FUNCTION starts( cLine, cStart ) RETURN cStart == Left( cLine, Len( cStart ) ) -/* Strip path from filename */ -STATIC FUNCTION strip_path( cFileName ) - - LOCAL cName - LOCAL cExt - - hb_default( @cFileName, "" ) - - hb_FNameSplit( cFileName, NIL, @cName, @cExt ) - - RETURN cName + cExt - - FUNCTION __dbgInput( nRow, nCol, nWidth, cValue, bValid, cColor, nSize ) LOCAL nOldCursor := SetCursor( SC_NORMAL ) @@ -3371,21 +3393,23 @@ FUNCTION __dbgAlert( cMessage ) FUNCTION __dbgValToStr( uVal ) - LOCAL cType := ValType( uVal ) - - DO CASE - CASE uVal == NIL ; RETURN "NIL" - CASE cType == "B" ; RETURN "{|| ... }" - CASE cType == "A" ; RETURN "{ ... }" - CASE cType $ "CM" ; RETURN '"' + uVal + '"' - CASE cType == "L" ; RETURN iif( uVal, ".T.", ".F." ) - CASE cType == "D" ; RETURN DToC( uVal ) - CASE cType == "T" ; RETURN hb_TToC( uVal ) - CASE cType == "N" ; RETURN Str( uVal ) - CASE cType == "O" ; RETURN "Class " + uVal:ClassName() + " object" - CASE cType == "H" ; RETURN "Hash of " + hb_ntos( Len( uVal ) ) + " elements" - CASE cType == "P" ; RETURN "Pointer" - ENDCASE + SWITCH ValType( uVal ) + CASE "B" ; RETURN "{|| ... }" + CASE "A" ; RETURN "{ ... }" + CASE "C" + CASE "M" ; RETURN '"' + uVal + '"' + CASE "L" ; RETURN iif( uVal, ".T.", ".F." ) + CASE "D" ; RETURN DToC( uVal ) + CASE "T" ; RETURN hb_TToC( uVal ) + CASE "N" ; RETURN Str( uVal ) + CASE "O" ; RETURN "Class " + uVal:ClassName() + " object" + CASE "H" ; RETURN "Hash of " + hb_ntos( Len( uVal ) ) + " elements" + CASE "P" ; RETURN "Pointer" + OTHERWISE + IF uVal == NIL + RETURN "NIL" + ENDIF + ENDSWITCH RETURN "U"