debug

  Previous topic Next topic JavaScript is required for the print function Mail us feedback on this topic! Mail us feedback on this topic!  
c:\harbour\source\debug
dbgentry.c
TypeFunctionSourceLine
STATIC VOIDhb_dbgActivate( HB_DEBUGINFO *info )
static void
hb_dbgActivate( HB_DEBUGINFO *info )
{
   PHB_DYNS pDynSym = hb_dynsymFind( "__DBGENTRY" );

   if( pDynSym && hb_dynsymIsFunction( pDynSym ) )
   {
      int i;
      PHB_ITEM aCallStack = hb_itemArrayNew( info->nCallStackLen );
      PHB_ITEM aModules;
      PHB_ITEM aBreak;

      for ( i = 0; i < info->nCallStackLen; i++ )
      {
         HB_CALLSTACKINFO *pEntry = &info->aCallStack[ i ];
         PHB_ITEM aEntry = hb_itemArrayNew( 6 );
         PHB_ITEM pItem;

         hb_arraySetC( aEntry, 1, pEntry->szModule );
         hb_arraySetC( aEntry, 2, pEntry->szFunction );
         hb_arraySetNL( aEntry, 3, pEntry->nLine );
         hb_arraySetNL( aEntry, 4, pEntry->nProcLevel );

         pItem = hb_dbgActivateVarArray( pEntry->nLocals, pEntry->aLocals );
         hb_arraySet( aEntry, 5, pItem );
         hb_itemRelease( pItem );

         pItem = hb_dbgActivateVarArray( pEntry->nStatics, pEntry->aStatics );
         hb_arraySet( aEntry, 6, pItem );
         hb_itemRelease( pItem );

         hb_arraySet( aCallStack, info->nCallStackLen - i, aEntry );
         hb_itemRelease( aEntry );
      }

      aModules = hb_dbgActivateModuleArray( info );
      aBreak = hb_dbgActivateBreakArray( info );

      hb_vmPushDynSym( pDynSym );
      hb_vmPushNil();
      hb_vmPushLong( HB_DBG_ACTIVATE );
      hb_vmPushPointer( info );
      hb_vmPushLong( info->nProcLevel );
      hb_vmPush( aCallStack );
      hb_vmPush( aModules );
      hb_vmPush( aBreak );

      hb_itemRelease( aCallStack );
      hb_itemRelease( aModules );
      hb_itemRelease( aBreak );

      hb_vmDo( 6 );
   }
}
dbgentry.c221
STATIC PHB_ITEMhb_dbgActivateBreakArray( HB_DEBUGINFO *info )
static PHB_ITEM
hb_dbgActivateBreakArray( HB_DEBUGINFO *info )
{
   int i;
   PHB_ITEM pArray = hb_itemArrayNew( info->nBreakPoints );

   for ( i = 0; i < info->nBreakPoints; i++ )
   {
      PHB_ITEM pBreak = hb_itemArrayNew( 3 );

      if ( !info->aBreak[ i ].szFunction )
      {
         hb_arraySetNI( pBreak, 1, info->aBreak[ i ].nLine );
         hb_arraySetC( pBreak, 2, info->aBreak[ i ].szModule );
      }
      else
      {
         hb_arraySetC( pBreak, 3, info->aBreak[ i ].szFunction );
      }

      hb_arraySet( pArray, i + 1, pBreak );
      hb_itemRelease( pBreak );
   }
   return pArray;
}
dbgentry.c277
STATIC PHB_ITEMhb_dbgActivateModuleArray( HB_DEBUGINFO *info )
static PHB_ITEM
hb_dbgActivateModuleArray( HB_DEBUGINFO *info )
{
   int i;
   PHB_ITEM pArray = hb_itemArrayNew( info->nModules );

   for ( i = 0; i < info->nModules; i++ )
   {
      PHB_ITEM pModule = hb_itemArrayNew( 4 );
      PHB_ITEM item;

      hb_arraySetC( pModule, 1, info->aModules[ i ].szModule );

      item = hb_dbgActivateVarArray( info->aModules[ i ].nStatics,
                                     info->aModules[ i ].aStatics );
      hb_arraySet( pModule, 2, item );
      hb_itemRelease( item );

      item = hb_dbgActivateVarArray( info->aModules[ i ].nGlobals,
                                     info->aModules[ i ].aGlobals );
      hb_arraySet( pModule, 3, item );
      hb_itemRelease( item );

      item = hb_dbgActivateVarArray( info->aModules[ i ].nExternGlobals,
                                     info->aModules[ i ].aExternGlobals );
      hb_arraySet( pModule, 4, item );
      hb_itemRelease( item );

      hb_arraySet( pArray, i + 1, pModule );
      hb_itemRelease( pModule );
   }
   return pArray;
}
dbgentry.c304
STATIC PHB_ITEMhb_dbgActivateVarArray( int nVars, HB_VARINFO *aVars )
static PHB_ITEM
hb_dbgActivateVarArray( int nVars, HB_VARINFO *aVars )
{
   int i;
   PHB_ITEM pArray = hb_itemArrayNew( nVars );

   for ( i = 0; i < nVars; i++ )
   {
      PHB_ITEM aVar = hb_itemArrayNew( 4 );

      hb_arraySetC( aVar, 1, aVars[ i ].szName );
      hb_arraySetNL( aVar, 2, aVars[ i ].nIndex );
      hb_arraySetCL( aVar, 3, &aVars[ i ].cType, 1 );
      hb_arraySetNL( aVar, 4, aVars[ i ].nFrame );

      hb_arraySet( pArray, i + 1, aVar );
      hb_itemRelease( aVar );
   }
   return pArray;
}
dbgentry.c339
HB_EXPORT VOIDhb_dbgEntry( int nMode, int nLine, char *szName, int nIndex, int nFrame )
HB_EXPORT void
hb_dbgEntry( int nMode, int nLine, char *szName, int nIndex, int nFrame )
{
   int i;
   ULONG nProcLevel;
   char szProcName[ HB_SYMBOL_NAME_LEN + HB_SYMBOL_NAME_LEN + 5 ];
   HB_DEBUGINFO *info = s_pInfo;

   if ( ( info->bInside || info->bQuit ) && nMode != HB_DBG_VMQUIT )
      return;

   switch ( nMode )
   {
      case HB_DBG_MODULENAME:
         HB_TRACE( HB_TR_DEBUG, ( "MODULENAME %s", szName ) );

         if ( szName[ strlen( szName ) - 1 ] == ':' )
            return;

         hb_procinfo( 0, szProcName, NULL, NULL );
         if ( !strncmp( szProcName, "(_INITSTATICS", 13 ) )
            info->bInitStatics = TRUE;
         else if ( !strncmp( szProcName, "(_INITGLOBALS", 13 ) )
            info->bInitGlobals = TRUE;
         else if ( !strncmp( szProcName, "(_INITLINES", 11 ) )
            info->bInitLines = TRUE;

         if ( info->bInitStatics || info->bInitGlobals )
            hb_dbgAddModule( info, szName );
         else if ( !strncmp( szProcName, "(b)", 3 ) )
            info->bCodeBlock = TRUE;
         else if ( info->bNextRoutine )
            info->bNextRoutine = FALSE;

         hb_dbgAddStack( info, szName, hb_dbg_ProcLevel() );
         for ( i = 0; i < info->nBreakPoints; i++ )
         {
            if ( info->aBreak[ i ].szFunction
                 && !strcmp( info->aBreak[ i ].szFunction, szProcName ) )
            {
               hb_dbg_InvokeDebug( TRUE );
               break;
            }
         }
         return;

      case HB_DBG_LOCALNAME:
         HB_TRACE( HB_TR_DEBUG, ( "LOCALNAME %s index %d", szName, nIndex ) );

         hb_dbgAddLocal( info, szName, nIndex, hb_dbg_ProcLevel() );
         return;

      case HB_DBG_STATICNAME:
         HB_TRACE( HB_TR_DEBUG, ( "STATICNAME %s index %d frame %d", szName, nIndex, nFrame ) );

         hb_dbgAddStatic( info, szName, nIndex, nFrame );
         return;

      case HB_DBG_SHOWLINE:
      {
         HB_CALLSTACKINFO *pTop = &info->aCallStack[ info->nCallStackLen - 1 ];
         BOOL bOldClsScope;

         HB_TRACE( HB_TR_DEBUG, ( "SHOWLINE %d", nLine ) );

         nProcLevel = hb_dbg_ProcLevel();

         /* Check if we've hit a tracepoint */
         bOldClsScope = hb_clsSetScope( FALSE );
         for ( i = 0; i < info->nTracePoints; i++ )
         {
            HB_TRACEPOINT *tp = &info->aTrace[ i ];
            PHB_ITEM xValue;

            xValue = hb_dbgEval( info, &info->aWatch[ tp->nIndex ] );
            if ( !xValue )
               xValue = hb_itemNew( NULL );

            if ( HB_ITEM_TYPE( xValue ) != HB_ITEM_TYPE( tp->xValue ) ||
                 !hb_dbgEqual( xValue, tp->xValue ) )
            {
               hb_itemCopy( tp->xValue, xValue );
               hb_itemRelease( xValue );

               pTop->nLine = nLine;
               info->nProcLevel = nProcLevel - ( hb_dbgIsAltD() ? 2 : 0 );
               info->bTraceOver = FALSE;
               info->bCodeBlock = FALSE;
               info->bGo = FALSE;
               if ( info->bToCursor )
               {
                  info->bToCursor = FALSE;
                  FREE( info->szToCursorModule );
               }
               info->bNextRoutine = FALSE;

               hb_dbgActivate( info );
               return;
            }
            hb_itemRelease( xValue );
         }
         hb_clsSetScope( bOldClsScope );

         if ( hb_dbgIsBreakPoint( info, pTop->szModule, nLine )
              || hb_dbg_InvokeDebug( FALSE )
              || ( info->pFunInvoke && info->pFunInvoke() ) )
         {
            info->bTraceOver = FALSE;
            if ( info->bToCursor )
            {
               info->bToCursor = FALSE;
               FREE( info->szToCursorModule );
            }
            info->bNextRoutine = FALSE;
            info->bGo = FALSE;
         }

         /* Check if we must skip every level above info->nTraceLevel */
         if ( info->bTraceOver )
         {
            if ( info->nTraceLevel < info->nCallStackLen )
               return;
            info->bTraceOver = FALSE;
         }

         /* Check if we're skipping to a specific line of source */
         if ( info->bToCursor )
         {
            if ( nLine == info->nToCursorLine
                 && FILENAME_EQUAL( pTop->szModule, info->szToCursorModule ) )
            {
               FREE( info->szToCursorModule );
               info->bToCursor = FALSE;
            }
            else
            {
               return;
            }
         }

         /* Check if'we skipping to the end of current routine */
         if ( info->bNextRoutine )
            return;

         if ( info->bCodeBlock )
         {
            info->bCodeBlock = FALSE;
            if ( !info->bCBTrace )
               return;
         }

         pTop->nLine = nLine;
         if ( !info->bGo )
         {
            info->nProcLevel = nProcLevel - ( hb_dbgIsAltD() ? 2 : 0 );
            hb_dbgActivate( info );
         }
         return;
      }

      case HB_DBG_ENDPROC:
         if ( info->bQuit )
            return;

         HB_TRACE( HB_TR_DEBUG, ( "ENDPROC", nLine ) );

         if ( info->bInitLines )
         {
            hb_dbgAddStopLines( info, hb_stackReturnItem() );
         }
         info->bCodeBlock = FALSE;
         info->bInitStatics = FALSE;
         info->bInitGlobals = FALSE;
         info->bInitLines = FALSE;
         hb_dbgEndProc( info );
         return;

      case HB_DBG_VMQUIT:
         hb_dbgQuit( info );
         return;
   }
}
dbgentry.c361
STATIC CHAR *hb_dbgStripModuleName( char * szName )
static char *
hb_dbgStripModuleName( char * szName )
{
   char * ptr;

   if( ( ptr = strrchr( szName, '/' ) ) != NULL )
   {
      szName = ptr + 1;
   }
   if( ( ptr = strrchr( szName, '\\' ) ) != NULL )
   {
      szName = ptr + 1;
   }

   return szName;
}
dbgentry.c545
HB_EXPORT VOIDhb_dbgAddBreak( void *handle, char *cModule, int nLine, char *szFunction )
HB_EXPORT void
hb_dbgAddBreak( void *handle, char *cModule, int nLine, char *szFunction )
{
   HB_DEBUGINFO *info = (HB_DEBUGINFO *)handle;
   HB_BREAKPOINT *pBreak;

   pBreak = ARRAY_ADD( HB_BREAKPOINT, info->aBreak, info->nBreakPoints );
   pBreak->szModule = STRDUP( cModule );
   pBreak->nLine = nLine;
   if ( szFunction )
   {
      pBreak->szFunction = STRDUP( szFunction );
   }
   else
   {
      pBreak->szFunction = NULL;
   }
}
dbgentry.c563
STATIC VOIDhb_dbgAddLocal( HB_DEBUGINFO *info, char *szName, int nIndex, int nFrame )
static void
hb_dbgAddLocal( HB_DEBUGINFO *info, char *szName, int nIndex, int nFrame )
{
   if ( info->bInitGlobals )
   {
      HB_MODULEINFO *module = &info->aModules[ info->nModules - 1 ];

      hb_dbgAddVar( &module->nGlobals, &module->aGlobals, szName, 'G', nIndex, hb_dbg_vmVarGCount() );
   }
   else
   {
      HB_CALLSTACKINFO *top = &info->aCallStack[ info->nCallStackLen - 1 ];

      hb_dbgAddVar( &top->nLocals, &top->aLocals, szName, 'L', nIndex, nFrame );
   }
}
dbgentry.c583
STATIC VOIDhb_dbgAddModule( HB_DEBUGINFO *info, char *szName )
static void
hb_dbgAddModule( HB_DEBUGINFO *info, char *szName )
{
   char * szModuleName;
   char * szFuncName;
   int iLen;

   szName = hb_dbgStripModuleName( szName );
   szFuncName = strrchr( szName, ':' );
   iLen = szFuncName ? ( int ) ( szFuncName - szName ) : ( int ) strlen( szName );
   STRNDUP( szModuleName, szName, iLen );

   if( !info->nModules || strcmp( info->aModules[ info->nModules - 1 ].szModule, szModuleName ) )
   {
      HB_MODULEINFO *pModule;

      pModule = ARRAY_ADD( HB_MODULEINFO, info->aModules, info->nModules );
      pModule->szModule = szModuleName;
      pModule->nStatics = 0;
      pModule->nGlobals = 0;
      pModule->nExternGlobals = 0;
   }
   else
   {
      FREE( szModuleName );
   }
}
dbgentry.c601
STATIC VOIDhb_dbgAddStack( HB_DEBUGINFO *info, char *szName, int nProcLevel )
static void
hb_dbgAddStack( HB_DEBUGINFO *info, char *szName, int nProcLevel )
{
   char szBuff[ HB_SYMBOL_NAME_LEN + HB_SYMBOL_NAME_LEN + 5 ];
   HB_CALLSTACKINFO *top;
   char *szFunction = strrchr( szName, ':' );

   if ( szFunction )
   {
      szFunction++;
   }
   top = ARRAY_ADD( HB_CALLSTACKINFO, info->aCallStack, info->nCallStackLen );
   if ( info->bCodeBlock )
   {
      memcpy( szBuff, "(b)", 3 );
      hb_strncpy( szBuff + 3, szFunction, sizeof( szBuff ) - 4 );
      top->szFunction = STRDUP( szBuff );
   }
   else
   {
      if ( szFunction )
      {
         top->szFunction = STRDUP( szFunction );
      }
      else
      {
         /* We're in an (_INITSTATICSnnnnn) pseudo-function */
         hb_procinfo( 0, szBuff, NULL, NULL );
         top->szFunction = STRDUP( szBuff );
      }
   }
   szName = hb_dbgStripModuleName( szName );
   if ( szFunction )
   {
      STRNDUP( top->szModule, szName, szFunction - szName - 1 );
   }
   else
   {
      top->szModule = STRDUP( szName );
   }
   top->nProcLevel = nProcLevel;
   top->nLine = 0;
   top->nLocals = 0;
   top->nStatics = 0;
}
dbgentry.c630
STATIC VOIDhb_dbgAddStatic( HB_DEBUGINFO *info, char *szName, int nIndex, int nFrame )
static void
hb_dbgAddStatic( HB_DEBUGINFO *info, char *szName, int nIndex, int nFrame )
{
   if ( info->bInitGlobals )
   {
      HB_MODULEINFO *module = &info->aModules[ info->nModules - 1 ];

      hb_dbgAddVar( &module->nExternGlobals, &module->aExternGlobals, szName,
                    'G', nIndex, hb_dbg_vmVarGCount() );
   }
   else if ( info->bInitStatics )
   {
      HB_MODULEINFO *module = &info->aModules[ info->nModules - 1 ];

      hb_dbgAddVar( &module->nStatics, &module->aStatics, szName, 'S', nIndex, nFrame );
   }
   else
   {
      HB_CALLSTACKINFO *top = &info->aCallStack[ info->nCallStackLen - 1 ];

      hb_dbgAddVar( &top->nStatics, &top->aStatics, szName, 'S', nIndex, nFrame );
   }
}
dbgentry.c677
STATIC VOIDhb_dbgAddStopLines( HB_DEBUGINFO *info, PHB_ITEM pItem )
static void
hb_dbgAddStopLines( HB_DEBUGINFO *info, PHB_ITEM pItem )
{
   int i, nLinesLen;

   if ( !info->pStopLines )
   {
      info->pStopLines = hb_itemNew( pItem );
   }
   else
   {
      int j;
      int nItemLen = hb_itemSize( pItem );

      nLinesLen = hb_itemSize( info->pStopLines );

      for ( i = 1; i <= nItemLen; i++ )
      {
         PHB_ITEM pEntry = hb_arrayGetItemPtr( pItem, i );
         char *szModule = hb_arrayGetCPtr( pEntry, 1 );
         BOOL bFound = FALSE;

         szModule = hb_dbgStripModuleName( szModule );
         for ( j = 1; j <= nLinesLen; j++ )
         {
            PHB_ITEM pLines = hb_arrayGetItemPtr( info->pStopLines, j );

            if ( !strcmp( hb_arrayGetCPtr( pLines, 1 ), szModule ) )
            {
               /* Merge stopline info */
               int nOrigMin = hb_arrayGetNL( pLines, 2 );
               int nNewMin = hb_arrayGetNL( pEntry, 2 );
               int nOrigLen = hb_arrayGetCLen( pLines, 3 );
               int nNewLen = hb_arrayGetCLen( pEntry, 3 );
               int nMin = HB_MIN( nNewMin, nOrigMin );
               int nMax = HB_MAX( nNewMin + nNewLen * 8, nOrigMin + nOrigLen * 8 );
               char *pOrigBuffer = hb_arrayGetCPtr( pLines, 3 );
               char *pNewBuffer = hb_arrayGetCPtr( pEntry, 3 );
               int nLen = ( nMax + 1 - nMin + 7 ) / 8 + 1;
               int k;
               char *pBuffer = (char *) hb_xgrab( nLen );

               hb_xmemset( pBuffer, 0, nLen );

               memmove( &( pBuffer[ ( nNewMin - nMin ) / 8 ] ), pNewBuffer, nNewLen );
               for ( k = 0; k < nOrigLen; k++ )
               {
                  pBuffer[ nOrigMin / 8 + k - nMin / 8 ] |= pOrigBuffer[ k ];
               }
               hb_arraySetNL( pLines, 2, nMin );
               if( !hb_arraySetCPtr( pLines, 3, pBuffer, nLen - 1 ) )
                  hb_xfree( pBuffer );
               bFound = TRUE;
               break;
            }
         }
         if ( !bFound )
         {
            hb_arrayAddForward( info->pStopLines, pEntry );
         }
      }
   }
   nLinesLen = hb_itemSize( info->pStopLines );
   for ( i = 1; i <= nLinesLen; i++ )
   {
      PHB_ITEM pEntry = hb_arrayGetItemPtr( info->pStopLines, i );
      char *szModule = hb_arrayGetCPtr( pEntry, 1 );

      if( szModule )
      {
         char *szName = hb_dbgStripModuleName( szModule );

         if( szName != szModule )
         {
            hb_arraySetC( pEntry, 1, szName );
         }
      }
   }
}
dbgentry.c702
STATIC VOIDhb_dbgAddVar( int *nVars, HB_VARINFO **aVars, char *szName, char cType, int nIndex, int nFrame )
static void
hb_dbgAddVar( int *nVars, HB_VARINFO **aVars, char *szName, char cType, int nIndex, int nFrame )
{
   HB_VARINFO *var;

   var = ARRAY_ADD( HB_VARINFO, *aVars, *nVars );
   var->szName = szName;
   var->cType = cType;
   var->nIndex = nIndex;
   var->nFrame = nFrame;
}
dbgentry.c783
HB_EXPORT VOIDhb_dbgAddWatch( void *handle, char *szExpr, BOOL bTrace )
HB_EXPORT void
hb_dbgAddWatch( void *handle, char *szExpr, BOOL bTrace )
{
   HB_DEBUGINFO *info = (HB_DEBUGINFO *)handle;
   HB_WATCHPOINT *pWatch;

   pWatch = ARRAY_ADD( HB_WATCHPOINT, info->aWatch, info->nWatchPoints );
   pWatch->szExpr = STRDUP( szExpr );
   pWatch->pBlock = NULL;
   pWatch->nVars = 0;

   if ( bTrace )
   {
     HB_TRACEPOINT *pTrace = ARRAY_ADD( HB_TRACEPOINT, info->aTrace, info->nTracePoints );

     pTrace->nIndex = info->nWatchPoints - 1;
     pTrace->xValue = hb_dbgEval( info, pWatch );
   }
}
dbgentry.c796
STATIC VOIDhb_dbgClearWatch( HB_WATCHPOINT *pWatch )
static void
hb_dbgClearWatch( HB_WATCHPOINT *pWatch )
{
   FREE( pWatch->szExpr );
   if ( pWatch->pBlock )
   {
      hb_itemRelease( pWatch->pBlock );
   }
   if ( pWatch->nVars )
   {
      int i;

      for (i = 0; i < pWatch->nVars; i++)
      {
         FREE( pWatch->aVars[ i ] );
      }
      FREE( pWatch->aVars );
   }
}
dbgentry.c817
HB_EXPORT VOIDhb_dbgDelBreak( void *handle, int nBreak )
HB_EXPORT void
hb_dbgDelBreak( void *handle, int nBreak )
{
   HB_DEBUGINFO *info = (HB_DEBUGINFO *)handle;
   HB_BREAKPOINT *pBreak = &info->aBreak[ nBreak ];

   FREE( pBreak->szModule );
   if ( pBreak->szFunction )
   {
      FREE( pBreak->szFunction );
   }
   ARRAY_DEL( HB_BREAKPOINT, info->aBreak, info->nBreakPoints, nBreak );
}
dbgentry.c838
HB_EXPORT VOIDhb_dbgDelWatch( void *handle, int nWatch )
HB_EXPORT void
hb_dbgDelWatch( void *handle, int nWatch )
{
   HB_DEBUGINFO *info = (HB_DEBUGINFO *)handle;
   HB_WATCHPOINT *pWatch = &info->aWatch[ nWatch ];
   int i;

   hb_dbgClearWatch( pWatch );
   ARRAY_DEL( HB_WATCHPOINT, info->aWatch, info->nWatchPoints, nWatch );

   for ( i = 0; i < info->nTracePoints; i++ )
   {
      HB_TRACEPOINT *pTrace = &info->aTrace[ i ];

      if ( pTrace->nIndex == nWatch )
      {
         if ( pTrace->xValue )
         {
            hb_itemRelease( pTrace->xValue );
         }
         ARRAY_DEL( HB_TRACEPOINT, info->aTrace, info->nTracePoints, i );
         i--;
      }
      else if ( pTrace->nIndex > nWatch )
      {
         pTrace->nIndex--;
      }
   }
}
dbgentry.c853
STATIC VOIDhb_dbgEndProc( HB_DEBUGINFO *info )
static void
hb_dbgEndProc( HB_DEBUGINFO *info )
{
   HB_CALLSTACKINFO *top;

   if ( !info->nCallStackLen )
      return;

   top = &info->aCallStack[ --info->nCallStackLen ];
   FREE( top->szFunction );
   FREE( top->szModule );
   if ( top->nLocals )
   {
      FREE( top->aLocals );
   }
   if ( top->nStatics )
   {
      FREE( top->aStatics );
   }
   if ( !info->nCallStackLen )
   {
      FREE( info->aCallStack );
      info->aCallStack = NULL;
   }
}
dbgentry.c884
STATIC BOOLhb_dbgEqual( PHB_ITEM pItem1, PHB_ITEM pItem2 )
static BOOL
hb_dbgEqual( PHB_ITEM pItem1, PHB_ITEM pItem2 )
{
   if ( HB_ITEM_TYPE( pItem1 ) != HB_ITEM_TYPE( pItem2 ) )
      return FALSE;
   if ( HB_IS_NIL( pItem1 ) )
      return HB_IS_NIL( pItem2 );
   if ( HB_IS_LOGICAL( pItem1 ) )
      return ( hb_itemGetL( pItem1 ) == hb_itemGetL( pItem2 ) );
   if ( HB_IS_POINTER( pItem1 ) )
      return ( hb_itemGetPtr( pItem1 ) == hb_itemGetPtr( pItem2 ) );
   if ( HB_IS_STRING( pItem1 ) )
      return !hb_itemStrCmp( pItem1, pItem2, TRUE );
   if ( HB_IS_NUMINT( pItem1 ) )
      return ( hb_itemGetNInt( pItem1 ) == hb_itemGetNInt( pItem2 ) );
   if ( HB_IS_NUMERIC( pItem1 ) )
      return ( hb_itemGetND( pItem1 ) == hb_itemGetND( pItem2 ) );
   if ( HB_IS_ARRAY( pItem1 ) )
      return ( hb_arrayId( pItem1 ) == hb_arrayId( pItem2 ) );
   if ( HB_IS_HASH( pItem1 ) )
      return ( hb_hashId( pItem1 ) == hb_hashId( pItem2 ) );
   return FALSE;
}
dbgentry.c911
STATIC PHB_ITEMhb_dbgEval( HB_DEBUGINFO *info, HB_WATCHPOINT *watch )
static PHB_ITEM
hb_dbgEval( HB_DEBUGINFO *info, HB_WATCHPOINT *watch )
{
   PHB_ITEM xResult = NULL;

   HB_TRACE( HB_TR_DEBUG, ( "expr %s", watch->szExpr ) );

   /* Check if we have a cached pBlock */
   if ( !watch->pBlock )
   {
      watch->pBlock = hb_dbgEvalMakeBlock( watch );
   }

   if ( watch->pBlock )
   {
      PHB_ITEM aVars = hb_dbgEvalResolve( info, watch );
      PHB_ITEM aNewVars = hb_itemArrayNew( watch->nVars );
      int i;

      hb_arrayCopy( aVars, aNewVars, NULL, NULL, NULL );

      info->bInside = TRUE;
      xResult = hb_itemDo( watch->pBlock, 1, aNewVars );
      info->bInside = FALSE;

      for ( i = 0; i < watch->nVars; i++ )
      {
         PHB_ITEM xOldValue = hb_itemArrayGet( aVars, i + 1 );
         PHB_ITEM xNewValue = hb_itemArrayGet( aNewVars, i + 1 );

         if ( !hb_dbgEqual( xOldValue, xNewValue ) )
         {
            hb_dbgVarSet( &watch->aScopes[ i ], xNewValue );
         }
         hb_itemRelease( xOldValue );
         hb_itemRelease( xNewValue );
      }

      hb_itemRelease( aVars );
      hb_itemRelease( aNewVars );
      for ( i = 0; i < watch->nVars; i++ )
      {
         if ( watch->aScopes[ i ].cType == 'M' )
         {
            FREE( watch->aScopes[ i ].szName );
         }
      }
      if ( watch->nVars )
      {
         FREE( watch->aScopes );
      }
   }
   return xResult;
}
dbgentry.c936
STATIC PHB_ITEMhb_dbgEvalMacro( char *szExpr, PHB_ITEM pItem )
static PHB_ITEM
hb_dbgEvalMacro( char *szExpr, PHB_ITEM pItem )
{
   PHB_ITEM pStr;
   const char *type;

   pStr = hb_itemPutC( NULL, szExpr );
   type = hb_macroGetType( pStr );
   hb_itemRelease( pStr );
   if ( ( !strcmp( type, "U" ) || !strcmp( type, "UE" ) ) )
   {
      return NULL;
   }
   hb_vmPushString( szExpr, strlen( szExpr ) );
   hb_macroGetValue( hb_stackItemFromTop( -1 ), 0, HB_SM_RT_MACRO );
   hb_itemForwardValue( pItem, hb_stackItemFromTop( -1 ) );
   hb_stackPop();
   return pItem;
}
dbgentry.c992
STATIC INThb_dbgEvalSubstituteVar( HB_WATCHPOINT *watch, char *szWord, int nStart, int nLen )
static int
hb_dbgEvalSubstituteVar( HB_WATCHPOINT *watch, char *szWord, int nStart, int nLen )
{
   int j;
   char *t;

   for ( j = 0; j < watch->nVars; j++ )
   {
      if ( !strcmp( szWord, watch->aVars[ j ] ) )
      {
         break;
      }
   }
   if ( j == watch->nVars )
   {
      *ARRAY_ADD( char *, watch->aVars, watch->nVars ) = szWord;
   }
   else
   {
      FREE( szWord );
   }

   t = (char *) ALLOC( strlen( watch->szExpr ) - nLen + 9 + 1 );
   memmove( t, watch->szExpr, nStart );
   memmove( t + nStart, "__dbg[", 6 );
   t[ nStart + 6 ] = '0' + ( char ) ( ( j + 1 ) / 10 );
   t[ nStart + 7 ] = '0' + ( char ) ( ( j + 1 ) % 10 );
   t[ nStart + 8 ] = ']';
   strcpy( t + nStart + 9, watch->szExpr + nStart + nLen );
   FREE( watch->szExpr );
   watch->szExpr = t;
   return nStart + 9;
}
dbgentry.c1016
STATIC PHB_ITEMhb_dbgEvalMakeBlock( HB_WATCHPOINT *watch )
static PHB_ITEM
hb_dbgEvalMakeBlock( HB_WATCHPOINT *watch )
{
   int i = 0;
   PHB_ITEM pBlock;
   BOOL bAfterId = FALSE;
   char *s;
   int buffsize;

   watch->nVars = 0;
   while ( watch->szExpr[ i ] )
   {
      char c = watch->szExpr[ i ];

      if ( IS_IDENT_START( c ) )
      {
         int nStart = i, nLen;
         int j = i;
         char *szWord;

         while ( c && IS_IDENT_CHAR( c ) )
         {
            j++;
            c = watch->szExpr[ j ];
         }
         nLen = j - i;
         STRNDUP( szWord, watch->szExpr + i, nLen );
         i = j;
         if ( c )
         {
            while ( watch->szExpr[ i ] && watch->szExpr[ i ] == ' ' )
            {
               i++;
            }
            if ( watch->szExpr[ i ] == '(' )
            {
               FREE( szWord );
               continue;
            }
            if ( watch->szExpr[ i ] == '-' && watch->szExpr[ i + 1 ] == '>' )
            {
               i += 2;
               while ( ( c = watch->szExpr[ i ] ) != '\0' && IS_IDENT_CHAR( c ) )
               {
                  i++;
               }
               FREE( szWord );
               continue;
            }
         }
         hb_strupr( szWord );
         i = hb_dbgEvalSubstituteVar( watch, szWord, nStart, nLen );
         bAfterId = TRUE;
         continue;
      }
      if ( c == '.' )
      {
         if ( watch->szExpr[ i + 1 ]
              && strchr( "TtFf", watch->szExpr[ i + 1 ] )
              && watch->szExpr[ i + 2 ] == '.' )
         {
            i += 3;
         }
         else if ( !hb_strnicmp( watch->szExpr + i + 1, "OR.", 3 ) )
         {
            i += 4;
         }
         else if ( !hb_strnicmp( watch->szExpr + i + 1, "AND.", 4 )
                   || !hb_strnicmp( watch->szExpr + i + 1, "NOT.", 4 ) )
         {
            i += 5;
         }
         else
         {
            i++;
         }
         bAfterId = FALSE;
         continue;
      }
      if ( c == ':'
           || ( c == '-' && watch->szExpr[ i + 1 ] == '>'
                && IS_IDENT_START( watch->szExpr[ i + 2 ] ) ) )
      {
         if ( c == ':' && watch->szExpr[ i + 1 ] == ':' )
         {
            i = hb_dbgEvalSubstituteVar( watch, hb_strdup( "SELF" ), i, 1 );
            bAfterId = TRUE;
            continue;
         }
         if ( c == '-' )
         {
            i++;
         }
         i++;
         while ( watch->szExpr[ i ] && IS_IDENT_CHAR( watch->szExpr[ i ] ) )
         {
            i++;
         }
         bAfterId = TRUE;
         continue;
      }
      if ( strchr( " !#$=<>(+-*/%^|,{&", c ) )
      {
         i++;
         bAfterId = FALSE;
         continue;
      }
      if ( c == '\'' || c == '\"' )
      {
         i++;
         while ( watch->szExpr[ i ] && watch->szExpr[ i ] != c )
         {
            i++;
         }
         if ( watch->szExpr[ i ] )
         {
            i++;
         }
         bAfterId = TRUE;
         continue;
      }
      if ( c == '[' )
      {
         i++;
         if ( bAfterId )
         {
            bAfterId = FALSE;
         }
         else
         {
            while ( watch->szExpr[ i ] && watch->szExpr[ i ] != ']' )
            {
               i++;
            }
            if ( watch->szExpr[ i ] )
            {
               i++;
            }
            bAfterId = TRUE;
         }
         continue;
      }
      i++;
   }

   buffsize = 8 + strlen( watch->szExpr ) + 1;

   s = ( char * ) ALLOC( buffsize + 1 );
   hb_strncpy( s, "{|__dbg|", buffsize );
   hb_strncat( s, watch->szExpr, buffsize );
   hb_strncat( s, "}", buffsize );
   pBlock = hb_itemNew( NULL );

   if( ! hb_dbgEvalMacro( s, pBlock ) )
   {
      hb_itemRelease( pBlock );
      pBlock = NULL;
   }
   FREE( s );

   return pBlock;
}
dbgentry.c1051
STATIC PHB_ITEMhb_dbgEvalResolve( HB_DEBUGINFO *info, HB_WATCHPOINT *watch )
static PHB_ITEM
hb_dbgEvalResolve( HB_DEBUGINFO *info, HB_WATCHPOINT *watch )
{
   int i;
   HB_CALLSTACKINFO *top = &info->aCallStack[ info->nCallStackLen - 1 ];
   PHB_ITEM aVars = hb_itemArrayNew( watch->nVars );
   HB_VARINFO *scopes;
   HB_MODULEINFO *module = NULL;
   int nProcLevel;

   if ( !watch->nVars )
   {
      return aVars;
   }

   scopes = (HB_VARINFO *) ALLOC( watch->nVars * sizeof( HB_VARINFO ) );
   nProcLevel = hb_dbg_ProcLevel();

   for ( i = 0; i < info->nModules; i++ )
   {
      if ( !strcmp( info->aModules[ i ].szModule, top->szModule ) )
      {
         module = &info->aModules[ i ];
         break;
      }
   }

   for ( i = 0; i < watch->nVars; i++ )
   {
      char *name = watch->aVars[ i ];
      HB_VARINFO *var;
      int j;
      PHB_ITEM pItem;

      for ( j = 0; j < top->nLocals; j++ )
      {
         var = &top->aLocals[ j ];
         if ( !strcmp( name, var->szName ) )
         {
            scopes[ i ].cType = 'L';
            scopes[ i ].nFrame = nProcLevel - var->nFrame;
            scopes[ i ].nIndex = var->nIndex;
            hb_itemArrayPut( aVars, i + 1, hb_dbgVarGet( &scopes[ i ] ) );
            break;
         }
      }
      if ( j < top->nLocals )
         continue;

      for ( j = 0; j < top->nStatics; j++ )
      {
         var = &top->aStatics[ j ];
         if ( !strcmp( name, var->szName ) )
         {
            scopes[ i ].cType = 'S';
            scopes[ i ].nFrame = var->nFrame;
            scopes[ i ].nIndex = var->nIndex;
            hb_itemArrayPut( aVars, i + 1, hb_dbgVarGet( &scopes[ i ] ) );
            break;
         }
      }
      if ( j < top->nStatics )
         continue;

      if ( module )
      {
         for ( j = 0; j < module->nStatics; j++ )
         {
            var = &module->aStatics[ j ];
            if ( !strcmp( name, var->szName ) )
            {
               scopes[ i ].cType = 'S';
               scopes[ i ].nFrame = var->nFrame;
               scopes[ i ].nIndex = var->nIndex;
               hb_itemArrayPut( aVars, i + 1, hb_dbgVarGet( &scopes[ i ] ) );
               break;
            }
         }
         if ( j < module->nStatics )
            continue;

         for ( j = 0; j < module->nGlobals; j++ )
         {
            var = &module->aGlobals[ j ];
            if ( !strcmp( name, var->szName ) )
            {
               scopes[ i ].cType = 'G';
               scopes[ i ].nFrame = var->nFrame;
               scopes[ i ].nIndex = var->nIndex;
               hb_itemArrayPut( aVars, i + 1, hb_dbgVarGet( &scopes[ i ] ) );
               break;
            }
         }
         if ( j < module->nGlobals )
            continue;

         for ( j = 0; j < module->nExternGlobals; j++ )
         {
            var = &module->aExternGlobals[ j ];
            if ( !strcmp( name, var->szName ) )
            {
               scopes[ i ].cType = 'G';
               scopes[ i ].nFrame = var->nFrame;
               scopes[ i ].nIndex = var->nIndex;
               hb_itemArrayPut( aVars, i + 1, hb_dbgVarGet( &scopes[ i ] ) );
               break;
            }
         }
         if ( j < module->nExternGlobals )
            continue;
      }

      scopes[ i ].cType = 'M';
      scopes[ i ].szName = STRDUP( name );
      pItem = hb_dbgVarGet( &scopes[ i ] );
      if ( pItem )
      {
         hb_itemArrayPut( aVars, i + 1, pItem );
      }
      if ( scopes[ i ].cType == 'F' )
      {
         hb_itemRelease( pItem );
      }
   }
   watch->aScopes = scopes;
   return aVars;
}
dbgentry.c1215
HB_EXPORT PHB_ITEMhb_dbgGetExpressionValue( void *handle, char *expression )
HB_EXPORT PHB_ITEM
hb_dbgGetExpressionValue( void *handle, char *expression )
{
   HB_DEBUGINFO *info = (HB_DEBUGINFO *)handle;
   PHB_ITEM result;
   HB_WATCHPOINT point;

   point.szExpr = STRDUP( expression );
   point.pBlock = NULL;
   point.nVars = 0;

   result = hb_dbgEval( info, &point );

   hb_dbgClearWatch( &point );

   return result;
}
dbgentry.c1344
HB_EXPORT PHB_ITEMhb_dbgGetSourceFiles( void *handle )
HB_EXPORT PHB_ITEM
hb_dbgGetSourceFiles( void *handle )
{
   HB_DEBUGINFO *info = (HB_DEBUGINFO *)handle;
   int nModules = hb_itemSize( info->pStopLines );
   PHB_ITEM ret = hb_itemArrayNew( nModules );
   int i;

   for ( i = 1; i <= nModules; i++ )
   {
      hb_arraySet( ret, i, hb_arrayGetItemPtr( hb_arrayGetItemPtr( info->pStopLines, i ), 1 ) );
   }
   return ret;
}
dbgentry.c1363
HB_EXPORT PHB_ITEMhb_dbgGetWatchValue( void *handle, int nWatch )
HB_EXPORT PHB_ITEM
hb_dbgGetWatchValue( void *handle, int nWatch )
{
   HB_DEBUGINFO *info = (HB_DEBUGINFO *)handle;

   return hb_dbgEval( info, &( info->aWatch[ nWatch ] ) );
}
dbgentry.c1379
STATIC BOOLhb_dbgIsAltD( void )
static BOOL
hb_dbgIsAltD( void )
{
   char szName[ HB_SYMBOL_NAME_LEN + HB_SYMBOL_NAME_LEN + 5];

   hb_procinfo( 1, szName, NULL, NULL );
   return !strcmp( szName, "ALTD" );
}
dbgentry.c1388
STATIC BOOLhb_dbgIsBreakPoint( HB_DEBUGINFO *info, char *szModule, int nLine )
static BOOL
hb_dbgIsBreakPoint( HB_DEBUGINFO *info, char *szModule, int nLine )
{
   int i;

   for ( i = 0; i < info->nBreakPoints; i++ )
   {
      HB_BREAKPOINT *point = &info->aBreak[ i ];

      if ( point->nLine == nLine
           && FILENAME_EQUAL( szModule, point->szModule ) )
         return TRUE;
   }
   return FALSE;
}
dbgentry.c1398
HB_EXPORT BOOLhb_dbgIsValidStopLine( void *handle, char *szModule, int nLine )
HB_EXPORT BOOL
hb_dbgIsValidStopLine( void *handle, char *szModule, int nLine )
{
   HB_DEBUGINFO *info = (HB_DEBUGINFO *)handle;
   int nModules = hb_itemSize( info->pStopLines );
   int i;

   for ( i = 1; i <= nModules; i++ )
   {
      PHB_ITEM pEntry = hb_arrayGetItemPtr( info->pStopLines, i );

      if ( FILENAME_EQUAL( hb_arrayGetCPtr( pEntry, 1 ), szModule ) )
      {
         int nMin = hb_arrayGetNL( pEntry, 2 );
         int nOfs = nLine - nMin;

         if ( nLine < nMin || (ULONG)( nOfs / 8 ) > hb_arrayGetCLen( pEntry, 3 ) )
         {
            return FALSE;
         }
         return ( hb_arrayGetCPtr( pEntry, 3 )[ nOfs / 8 ] & ( 1 << ( nOfs % 8 ) ) ) != 0;
      }
   }
   return FALSE;
}
dbgentry.c1415
STATIC VOIDhb_dbgQuit( HB_DEBUGINFO *info )
static void
hb_dbgQuit( HB_DEBUGINFO *info )
{
   while ( info->nWatchPoints )
   {
      hb_dbgDelWatch( info, info->nWatchPoints - 1 );
   }
   while ( info->nBreakPoints )
   {
      hb_dbgDelBreak( info, info->nBreakPoints - 1 );
   }
   while ( info->nCallStackLen )
   {
      hb_dbgEndProc( info );
   }
   if ( info->pStopLines )
   {
      hb_itemRelease( info->pStopLines );
   }
   while ( info->nModules )
   {
      int nModules = info->nModules - 1;
      HB_MODULEINFO *module = &info->aModules[ nModules ];
      if ( module->nStatics )
      {
         FREE( module->aStatics );
      }
      if ( module->szModule )
      {
         FREE( module->szModule );
      }
      ARRAY_DEL( HB_MODULEINFO, info->aModules, info->nModules, nModules );
   }
   if ( info->bToCursor )
   {
      info->bToCursor = FALSE;
      FREE( info->szToCursorModule );
   }
}
dbgentry.c1442
HB_EXPORT VOIDhb_dbgSetCBTrace( void *handle, BOOL bCBTrace )
HB_EXPORT void
hb_dbgSetCBTrace( void *handle, BOOL bCBTrace )
{
   HB_DEBUGINFO *info = (HB_DEBUGINFO *)handle;

   info->bCBTrace = bCBTrace;
}
dbgentry.c1483
HB_EXPORT VOIDhb_dbgSetGo( void *handle )
HB_EXPORT void
hb_dbgSetGo( void *handle )
{
   HB_DEBUGINFO *info = (HB_DEBUGINFO *)handle;

   info->bGo = TRUE;
}
dbgentry.c1492
HB_EXPORT VOID HB_DBGSETINVOKE( VOID *HANDLE, BOOL ( *PFUNINVOKE ( void ) )
HB_EXPORT void
hb_dbgSetInvoke( void *handle, BOOL ( *pFunInvoke )( void ) )
{
   HB_DEBUGINFO *info = (HB_DEBUGINFO *)handle;

   info->pFunInvoke = pFunInvoke;
}
dbgentry.c1501
HB_EXPORT VOIDhb_dbgSetNextRoutine( void *handle )
HB_EXPORT void
hb_dbgSetNextRoutine( void *handle )
{
   HB_DEBUGINFO *info = (HB_DEBUGINFO *)handle;

   info->bNextRoutine = TRUE;
}
dbgentry.c1510
HB_EXPORT VOIDhb_dbgSetQuit( void *handle )
HB_EXPORT void
hb_dbgSetQuit( void *handle )
{
   HB_DEBUGINFO *info = (HB_DEBUGINFO *)handle;

   info->bQuit = TRUE;
}
dbgentry.c1519
HB_EXPORT VOIDhb_dbgSetToCursor( void *handle, char *szModule, int nLine )
HB_EXPORT void
hb_dbgSetToCursor( void *handle, char *szModule, int nLine )
{
   HB_DEBUGINFO *info = (HB_DEBUGINFO *)handle;

   info->bToCursor = TRUE;
   info->szToCursorModule = STRDUP( szModule );
   info->nToCursorLine = nLine;
}
dbgentry.c1528
HB_EXPORT VOIDhb_dbgSetTrace( void *handle )
HB_EXPORT void
hb_dbgSetTrace( void *handle )
{
   HB_DEBUGINFO *info = (HB_DEBUGINFO *)handle;

   info->bTraceOver = TRUE;
   info->nTraceLevel = info->nCallStackLen;
}
dbgentry.c1539
HB_EXPORT VOIDhb_dbgSetWatch( void *handle, int nWatch, char *szExpr, BOOL bTrace )
HB_EXPORT void
hb_dbgSetWatch( void *handle, int nWatch, char *szExpr, BOOL bTrace )
{
   HB_DEBUGINFO *info = (HB_DEBUGINFO *)handle;
   HB_WATCHPOINT *pWatch = &info->aWatch[ nWatch ];
   int i;

   hb_dbgClearWatch( pWatch );
   pWatch->szExpr = STRDUP( szExpr );
   pWatch->pBlock = NULL;
   for ( i = 0; i < info->nTracePoints; i++ )
   {
      HB_TRACEPOINT *pTrace = &info->aTrace[ i ];

      if ( pTrace->nIndex == nWatch )
      {
         if ( pTrace->xValue )
         {
            hb_itemRelease( pTrace->xValue );
         }
         ARRAY_DEL( HB_TRACEPOINT, info->aTrace, info->nTracePoints, i );
         break;
      }
   }
   if ( bTrace )
   {
      HB_TRACEPOINT *pTrace = ARRAY_ADD( HB_TRACEPOINT, info->aTrace, info->nTracePoints );

      pTrace->nIndex = nWatch;
      pTrace->xValue = hb_dbgEval( info, pWatch );
   }
}
dbgentry.c1549
STATIC PHB_ITEMhb_dbgVarGet( HB_VARINFO *scope )
static PHB_ITEM
hb_dbgVarGet( HB_VARINFO *scope )
{
   switch ( scope->cType )
   {
      case 'G':
         return hb_dbg_vmVarGGet( scope->nFrame, scope->nIndex );
      case 'L':
         return hb_dbg_vmVarLGet( scope->nFrame, scope->nIndex );
      case 'S':
         return hb_dbg_vmVarSGet( scope->nFrame, scope->nIndex );
      case 'M':
      {
         PHB_DYNS pDyn;

         pDyn = hb_dynsymFind( scope->szName );
         if ( pDyn != NULL )
         {
            PHB_ITEM pItem = hb_memvarGetValueBySym( pDyn );
            if( !pItem )
            {
               pItem = hb_itemNew( NULL );
               if ( hb_rddFieldGet( pItem, hb_dynsymSymbol( pDyn ) ) == SUCCESS )
               {
                  scope->cType = 'F';
               }
               else
               {
                  hb_itemRelease( pItem );
                  pItem = NULL;
               }
            }
            return pItem;
         }
      }
   }
   return NULL;
}
dbgentry.c1583
STATIC VOIDhb_dbgVarSet( HB_VARINFO *scope, PHB_ITEM xNewValue )
static void
hb_dbgVarSet( HB_VARINFO *scope, PHB_ITEM xNewValue )
{
   switch ( scope->cType )
   {
      case 'G':
      case 'L':
      case 'S':
         hb_itemCopy( hb_dbgVarGet( scope ), xNewValue );
         break;
      case 'M':
      {
         PHB_DYNS pDynSym = hb_dynsymFind( "__MVPUT" );

         if ( pDynSym && hb_dynsymIsFunction( pDynSym ) )
         {
            hb_vmPushDynSym( pDynSym );
            hb_vmPushNil();
            hb_vmPushString( scope->szName, strlen( scope->szName ) );
            hb_vmPush( xNewValue );
            hb_vmDo( 2 );
         }
         break;
      }
   }
}
dbgentry.c1623
HB_FUNC__DBGSETENTRY(void)
HB_FUNC( __DBGSETENTRY )
{
   hb_dbg_SetEntry( hb_dbgEntry );
}
dbgentry.c1650
HB_FUNC__DBGSETGO(void)
HB_FUNC( __DBGSETGO )
{
   void * ptr = hb_parptr( 1 );
   if( ptr )
      hb_dbgSetGo( ptr );
}
dbgentry.c1658
HB_FUNC__DBGSETTRACE(void)
HB_FUNC( __DBGSETTRACE )
{
   void * ptr = hb_parptr( 1 );
   if( ptr )
      hb_dbgSetTrace( ptr );
}
dbgentry.c1665
HB_FUNC__DBGSETCBTRACE(void)
HB_FUNC( __DBGSETCBTRACE )
{
   void * ptr = hb_parptr( 1 );
   if( ptr )
      hb_dbgSetCBTrace( ptr, hb_parl( 2 ) );
}
dbgentry.c1672
HB_FUNC__DBGSETNEXTROUTINE(void)
HB_FUNC( __DBGSETNEXTROUTINE )
{
   void * ptr = hb_parptr( 1 );
   if( ptr )
      hb_dbgSetNextRoutine( ptr );
}
dbgentry.c1679
HB_FUNC__DBGSETQUIT(void)
HB_FUNC( __DBGSETQUIT )
{
   void * ptr = hb_parptr( 1 );
   if( ptr )
      hb_dbgSetQuit( ptr );
}
dbgentry.c1686
HB_FUNC__DBGSETTOCURSOR(void)
HB_FUNC( __DBGSETTOCURSOR )
{
   void * ptr = hb_parptr( 1 );
   if( ptr )
      hb_dbgSetToCursor( ptr, hb_parc( 2 ), hb_parni( 3 ) );
}
dbgentry.c1693
HB_FUNC__DBGGETEXPRVALUE(void)
HB_FUNC( __DBGGETEXPRVALUE )
{
   void * ptr = hb_parptr( 1 );
   if( ptr )
   {
      PHB_ITEM pItem;

      if( ISCHAR( 2 ) )
         pItem = hb_dbgGetExpressionValue( hb_parptr( 1 ), hb_parc( 2 ) );
      else
         pItem = hb_dbgGetWatchValue( hb_parptr( 1 ), hb_parni( 2 ) - 1 );

      if( pItem )
      {
         hb_storl( TRUE, 3 );
         hb_itemRelease( hb_itemReturn( pItem ) );
      }
      else
         hb_storl( FALSE, 3 );
   }
}
dbgentry.c1700
HB_FUNC__DBGGETSOURCEFILES(void)
HB_FUNC( __DBGGETSOURCEFILES )
{
   void * ptr = hb_parptr( 1 );
   if( ptr )
      hb_itemRelease( hb_itemReturn( hb_dbgGetSourceFiles( ptr ) ) );
}
dbgentry.c1722
HB_FUNC__DBGISVALIDSTOPLINE(void)
HB_FUNC( __DBGISVALIDSTOPLINE )
{
   void * ptr = hb_parptr( 1 );
   if( ptr )
      hb_retl( hb_dbgIsValidStopLine( ptr, hb_parc( 2 ), hb_parni( 3 ) ) );
}
dbgentry.c1729
HB_FUNC__DBGADDBREAK(void)
HB_FUNC( __DBGADDBREAK )
{
   void * ptr = hb_parptr( 1 );
   if( ptr )
      hb_dbgAddBreak( ptr, hb_parc( 2 ), hb_parni( 3 ), NULL );
}
dbgentry.c1736
HB_FUNC__DBGDELBREAK(void)
HB_FUNC( __DBGDELBREAK )
{
   void * ptr = hb_parptr( 1 );
   if( ptr )
      hb_dbgDelBreak( ptr, hb_parni( 2 ) );
}
dbgentry.c1743
HB_FUNC__DBGADDWATCH(void)
HB_FUNC( __DBGADDWATCH )
{
   void * ptr = hb_parptr( 1 );
   if( ptr )
      hb_dbgAddWatch( ptr, hb_parc( 2 ), hb_parl( 3 ) );
}
dbgentry.c1750
HB_FUNC__DBGDELWATCH(void)
HB_FUNC( __DBGDELWATCH )
{
   void * ptr = hb_parptr( 1 );
   if( ptr )
      hb_dbgDelWatch( ptr, hb_parni( 2 ) );
}
dbgentry.c1757
HB_FUNC__DBGSETWATCH(void)
HB_FUNC( __DBGSETWATCH )
{
   void * ptr = hb_parptr( 1 );
   if( ptr )
      hb_dbgSetWatch( ptr, hb_parni( 2 ), hb_parc( 3 ), hb_parl( 4 ) );
}
dbgentry.c1764
HB_FUNC__DBGSENDMSG(void)
HB_FUNC( __DBGSENDMSG )
{
   hb_dbgObjSendMessage( hb_parnl( 1 ), hb_param( 2, HB_IT_ANY ),
                         hb_param( 3, HB_IT_ANY ), 4 );
}
dbgentry.c1771
dbgbrwsr.prg
TypeFunctionSourceLine
METHODNew( nTop, nLeft, nBottom, nRight, oParentWindow )
   METHOD New( nTop, nLeft, nBottom, nRight, oParentWindow )
dbgbrwsr.prg92
METHOD ADDCOLUMN( OCOL ) INLINEAAdd( ::aColumns, oCol ), ::colCount++, Self
   METHOD AddColumn( oCol )    INLINE AAdd( ::aColumns, oCol ), ::colCount++, Self
dbgbrwsr.prg93
METHODConfigure()
   METHOD Configure()
dbgbrwsr.prg94
METHODDeHiLite() INLINE Self
   METHOD DeHiLite()           INLINE Self
dbgbrwsr.prg95
METHOD DOWN() INLINE :MoveCursor( 1 )
   METHOD Down()               INLINE ::MoveCursor( 1 )
dbgbrwsr.prg96
METHODForceStable()
   METHOD ForceStable()
dbgbrwsr.prg97
METHODGetColumn( nColumn ) INLINE ::aColumns[ nColumn ]
   METHOD GetColumn( nColumn ) INLINE ::aColumns[ nColumn ]
dbgbrwsr.prg98
METHODGoTo( nRow )
   METHOD GoTo( nRow )
dbgbrwsr.prg99
METHOD GOTOP() INLINE ::GOTO( 1 ), ::ROWPOS := 1, ::NFIRSTVISIBLE := 1, :RefreshAll()
   METHOD GoTop()              INLINE ::GoTo( 1 ), ::rowPos := 1, ::nFirstVisible := 1, ::RefreshAll()
dbgbrwsr.prg100
METHODGoBottom()
   METHOD GoBottom()
dbgbrwsr.prg101
METHODHiLite() INLINE Self
   METHOD HiLite()             INLINE Self
dbgbrwsr.prg102
METHOD INVALIDATE() INLINE :RefreshAll()
   METHOD Invalidate()         INLINE ::RefreshAll()
dbgbrwsr.prg103
METHODMoveCursor( nSkip )
   METHOD MoveCursor( nSkip )
dbgbrwsr.prg104
METHOD PAGEDOWN() INLINE :MoveCursor( ::rowCount )
   METHOD PageDown()           INLINE ::MoveCursor( ::rowCount )
dbgbrwsr.prg105
METHOD PAGEUP() INLINE :MoveCursor( -::rowCount )
   METHOD PageUp()             INLINE ::MoveCursor( -::rowCount )
dbgbrwsr.prg106
METHOD REFRESHALL() INLINEAFill( ::aRowState, .F. ), Self
   METHOD RefreshAll()         INLINE AFill( ::aRowState, .F. ), Self
dbgbrwsr.prg107
METHOD REFRESHCURRENT() INLINEIIf( ::rowCount > 0, ::aRowState[ ::rowPos ] := .F., ), Self
   METHOD RefreshCurrent()     INLINE IIf( ::rowCount > 0, ::aRowState[ ::rowPos ] := .F., ), Self
dbgbrwsr.prg108
METHODResize( nTop, nLeft, nBottom, nRight )
   METHOD Resize( nTop, nLeft, nBottom, nRight )
dbgbrwsr.prg109
METHOD STABILIZE() INLINE :ForceStable()
   METHOD Stabilize()          INLINE ::ForceStable()
dbgbrwsr.prg110
METHOD UP() INLINE :MoveCursor( -1 )
   METHOD Up()                 INLINE ::MoveCursor( -1 )

ENDCLASS
dbgbrwsr.prg111
HBDBBROWSER:METHODNew( nTop, nLeft, nBottom, nRight, oParentWindow ) CLASS HBDbBrowser
METHOD New( nTop, nLeft, nBottom, nRight, oParentWindow ) CLASS HBDbBrowser

   ::Window := oParentWindow
   ::nTop := nTop
   ::nLeft := nLeft
   ::nBottom := nBottom
   ::nRight := nRight
   
   RETURN Self
dbgbrwsr.prg115
HBDBBROWSER:METHODConfigure()
METHOD Configure()
   ::rowCount := ::nBottom - ::nTop + 1
   ASize( ::aRowState, ::rowCount )
   ::aColorSpec := hb_aTokens( ::colorSpec, "," )
   ::lConfigured := .T.
   RETURN Self
dbgbrwsr.prg125
HBDBBROWSER:METHODMoveCursor( nSkip )
METHOD MoveCursor( nSkip )
   LOCAL nSkipped

   nSkipped := ::GoTo( ::rowPos + ::nFirstVisible - 1 + nSkip )
   IF !::hitBottom .OR. Abs( nSkipped ) > 0
      IF IIf( nSkipped > 0, ::rowPos + nSkipped <= ::rowCount, ::rowPos + nSkipped >= 1 )
         ::RefreshCurrent()
         ::rowPos += nSkipped
         ::RefreshCurrent()
      ELSE
         ::nFirstVisible := Max( 1, nSkipped + ::nFirstVisible )
         ::RefreshAll()
      ENDIF
   ENDIF
   RETURN Self
dbgbrwsr.prg132
HBDBBROWSER:METHODForceStable()
METHOD ForceStable()
   LOCAL nRow, nCol, xData, oCol, nColX, nWid, aClr, nClr

   IF !::lConfigured
       ::Configure()
   ENDIF
   FOR nRow := 1 TO ::rowCount
      IF Empty( ::aRowState[ nRow ] )
         ::GoTo( ::nFirstVisible + nRow - 1 )
         IF ::hitBottom
            DispOutAt( ::nTop + nRow - 1, ::nLeft, Space( ::nRight - ::nLeft + 1 ), ::aColorSpec[ 1 ] )
         ELSE
            nColX := ::nLeft
            FOR nCol := 1 TO Len( ::aColumns )
               IF nColX <= ::nRight
                  oCol := ::aColumns[ nCol ]
                  xData := Eval( oCol:block )
                  nClr := IIf( nRow == ::rowPos, 2, 1 )
                  aClr := Eval( oCol:colorBlock, xData )
                  IF VALTYPE( aClr ) == "A"
                     nClr := aClr[ nClr ]
                  ELSE
                     nClr := oCol:defColor[ nClr ]
                  ENDIF
                  IF oCol:width == NIL
                     nWid := Len( xData )
                  ELSE
                     nWid := oCol:width
                  ENDIF
                  DispOutAt( ::nTop + nRow - 1, nColX, PadR( xData, nWid ) + IIf( nCol < Len( ::aColumns ), " ", "" ), ::aColorSpec[ nClr ] )
                  nColX += nWid + 1
               ENDIF
            NEXT
         ENDIF
         ::aRowState[ nRow ] := .T.
      ENDIF
   NEXT
   ::GoTo( ::nFirstVisible + ::rowPos - 1 )
   SetPos( ::nTop + ::rowPos - 1, ::nLeft )
   RETURN Self
dbgbrwsr.prg148
HBDBBROWSER:METHODGoTo( nRow )
METHOD GoTo( nRow )
   LOCAL nOldRow := ::nFirstVisible + ::rowPos - 1
   LOCAL nSkipped := 0

   Eval( ::goTopBlock )
   IF nRow == 1
      ::hitBottom := .F.
   ELSE
      nSkipped := Eval( ::skipBlock, nRow - 1 )
      ::hitBottom := ( nSkipped != nRow - 1 )
   ENDIF
   RETURN nSkipped - nOldRow + 1
dbgbrwsr.prg189
HBDBBROWSER:METHODGoBottom()
METHOD GoBottom()
   DO WHILE !::hitBottom
      ::PageDown()
   ENDDO
   RETURN Self
dbgbrwsr.prg202
HBDBBROWSER:METHODResize( nTop, nLeft, nBottom, nRight )
METHOD Resize( nTop, nLeft, nBottom, nRight )
   LOCAL lResize := .F.

   IF nTop != NIL .AND. nTop != ::nTop
      ::nTop := nTop
      lResize := .T.
   ENDIF
   IF nLeft != NIL .AND. nLeft != ::nLeft
      ::nLeft := nLeft
      lResize := .T.
   ENDIF
   IF nBottom != NIL .AND. nBottom != ::nBottom
      ::nBottom := nBottom
      lResize := .T.
   ENDIF
   IF nRight != NIL .AND. nRight != ::nRight
      ::nRight := nRight
      lResize := .T.
   ENDIF

   IF lResize
      ::Configure():ForceStable()
   ENDIF
      
   RETURN self
dbgbrwsr.prg208
dbghelp.prg
TypeFunctionSourceLine
PROCEDURE__dbgHelp( nTopic )
PROCEDURE __dbgHelp( nTopic )

   LOCAL oDlg
   LOCAL cColor := iif( __Dbg():lMonoDisplay, "N/W, W/N, W+/W, W+/N", "N/W, N/BG, R/W, R/BG" )
   LOCAL oBrw
   LOCAL aTopics := GetTopics()

   DEFAULT nTopic TO 1

   oDlg := HBDbWindow():New( 2, 2, MaxRow() - 2, MaxCol() - 2, "Help", cColor )

   oBrw := HBDbBrowser():New( oDlg:nTop + 1, oDlg:nLeft + 1, oDlg:nBottom - 1, oDlg:nLeft + 12 )
   oBrw:Cargo := 1
   oBrw:AddColumn( TBColumnNew( "", { || aTopics[ oBrw:Cargo ][ 1 ] }, 12 ) )
   oBrw:ColorSpec := StrTran( __Dbg():ClrModal(), ", R/W", "" )
   oBrw:SkipBlock := { | nSkip, nOld | nOld := oBrw:Cargo, oBrw:Cargo += nSkip,;
                  oBrw:Cargo := Min( Max( oBrw:Cargo, 1 ), Len( aTopics ) ),;
                  oBrw:Cargo - nOld }
   oBrw:GoTopBlock := { || oBrw:Cargo := 1 }
   oBrw:GoBottomBlock := { || oBrw:Cargo := Len( aTopics ) }

   IF nTopic > 1
      Eval( oBrw:SkipBlock, nTopic - 1 )
   ENDIF

   oDlg:bPainted := { || PaintWindow( oDlg, oBrw, aTopics ) }
   oDlg:bKeyPressed := { | nKey | ProcessKey( nKey, oDlg, oBrw, aTopics, oDlg:cColor ) }

   oDlg:ShowModal()

   RETURN
dbghelp.prg65
STATIC PROCEDUREPaintWindow( oDlg, oBrw, aTopics )
STATIC PROCEDURE PaintWindow( oDlg, oBrw, aTopics )

   DispBox( oDlg:nTop + 1, oDlg:nLeft + 13, oDlg:nBottom - 1, oDlg:nLeft + 13, 1, oDlg:cColor )
   DispOutAt( oDlg:nTop , oDlg:nLeft + 13 , Chr( 194 ), oDlg:cColor )
   DispOutAt( oDlg:nBottom , oDlg:nLeft + 13 , Chr( 193 ), oDlg:cColor )

   oBrw:ForceStable()
   ShowTopic( oDlg, aTopics, oBrw:Cargo, 0 ) // Start on page 1

   RETURN
dbghelp.prg97
STATIC PROCEDUREProcessKey( nKey, oDlg, oBrw, aTopics )
STATIC PROCEDURE ProcessKey( nKey, oDlg, oBrw, aTopics )

   LOCAL n
   LOCAL nSkip

   DO CASE
   CASE nKey == K_UP

      IF oBrw:Cargo > 1
         oBrw:Up()
         oBrw:ForceStable()
         ShowTopic( oDlg, aTopics, oBrw:Cargo, 0 )  // Start on page 1
      ENDIF

   CASE nKey == K_DOWN

      IF oBrw:Cargo < Len( aTopics )
         oBrw:Down()
         oBrw:ForceStable()
         ShowTopic( oDlg, aTopics, oBrw:Cargo, 0 )  // Start on page 1
      ENDIF

   CASE nKey == K_HOME

      IF oBrw:Cargo > 1
         oBrw:GoTop()
         oBrw:ForceStable()
         ShowTopic( oDlg, aTopics, oBrw:Cargo, 0 )  // Start on page 1
      ENDIF

   CASE nKey == K_END

      IF oBrw:Cargo < Len( aTopics )
         oBrw:GoBottom()
         oBrw:ForceStable()
         ShowTopic( oDlg, aTopics, oBrw:Cargo, 0 )  // Start on page 1
      ENDIF

   CASE nKey == K_PGUP .OR. nKey == K_CTRL_B

      ShowTopic( oDlg, aTopics, oBrw:Cargo, -1 ) // Skip to prev page

   CASE nKey == K_PGDN .OR. nKey == K_CTRL_F .OR. nKey == K_SPACE

      ShowTopic( oDlg, aTopics, oBrw:Cargo, 1 )  // Skip to next page

   CASE nKey == K_LBUTTONDOWN

      IF ( nSkip := MRow() - oDlg:nTop - oBrw:RowPos ) != 0
         IF nSkip > 0
            FOR n := 1 TO nSkip
               oBrw:Down()
               oBrw:Stabilize()
            NEXT
         ELSE
            FOR n := 1 TO nSkip + 2 STEP -1
               oBrw:Up()
               oBrw:Stabilize()
            NEXT
         ENDIF
         oBrw:ForceStable()
         ShowTopic( oDlg, aTopics, oBrw:Cargo, 0 )  // Start on page 1
      ENDIF

   ENDCASE

   RETURN
dbghelp.prg108
STATIC PROCEDUREShowTopic( oDlg, aTopics, nTopic, nPageOp )
STATIC PROCEDURE ShowTopic( oDlg, aTopics, nTopic, nPageOp )

   local oDebug := __Dbg()
   LOCAL nRows  := oDlg:nBottom - oDlg:nTop - 1
   LOCAL nPages := Len( aTopics[ nTopic ][ 2 ] ) / nRows
   LOCAL nRowsToPaint
   LOCAL n

   IF nPages > 1 .AND. Int( nPages ) < nPages
      nPages := Int( nPages ) + 1
   ENDIF

   IF nPages == 1
      IF nPageOp == -1 .OR. nPageOp == 1
         RETURN
      ENDIF
      oDebug:nHelpPage := 1
   ELSE
      DO CASE
      CASE nPageOp == 0 // Show first page

         oDebug:nHelpPage := 1

      CASE nPageOp == 1 // Show next page

         IF oDebug:nHelpPage < nPages
            oDebug:nHelpPage++
         ELSE
            RETURN
         ENDIF

      CASE nPageOp == -1 // Show prev page

         IF oDebug:nHelpPage > 1
            oDebug:nHelpPage--
         ELSE
            RETURN
         ENDIF

      ENDCASE
   ENDIF

   Scroll( oDlg:nTop + 1, oDlg:nLeft + 14, oDlg:nBottom - 1, oDlg:nRight - 1 )

   nRowsToPaint := Min( nRows, Len( aTopics[ nTopic ][ 2 ] ) - ( ( oDebug:nHelpPage - 1 ) * nRows ) )

   FOR n := 1 TO nRowsToPaint
      DispOutAt( 2 + n, 16, aTopics[ nTopic ][ 2 ][ ( ( oDebug:nHelpPage - 1 ) * nRows ) + n ] )
   NEXT

   IF Len( aTopics[ nTopic ][ 2 ] ) <= nRows
      DispOutAt( oDlg:nBottom, oDlg:nRight - 16, " Page 1 of 1 " )
   ELSE
      DispOutAt( oDlg:nBottom, oDlg:nRight - 16, " Page " + Str( oDebug:nHelpPage, 1 ) + " of " + Str( nPages, 1 ) + " " )
   ENDIF

   RETURN
dbghelp.prg176
STATIC FUNCTIONGetTopics()
STATIC FUNCTION GetTopics()

   LOCAL aTopics := { { "About Help  ", },;
                      { "Keys        ", },;
                      { "   Function ", },;
                      { "   Window   ", },;
                      { "   Other    ", },;
                      { "Windows     ", },;
                      { "   Command  ", },;
                      { "   Code     ", },;
                      { "   Watch    ", },;
                      { "   Monitor  ", },;
                      { "   CallStack", },;
                      { "Menus       ", },;
                      { "   File     ", },;
                      { "   Locate   ", },;
                      { "   View     ", },;
                      { "   Run      ", },;
                      { "   Point    ", },;
                      { "   Monitor  ", },;
                      { "   Options  ", },;
                      { "   Window   ", },;
                      { "Commands    ", },;
                      { "Script files", } }

   aTopics[ 1 ][ 2 ] := ;
      { " " + Chr( 24 ) + Chr( 25 ) + "             Select help topic.",;
        " PageUp         Page help text down.",;
        " PageDn         Page help text down.",;
        " Esc            Returns to debugger." }

   aTopics[ 2 ][ 2 ] := ;
      { "Special debugger keys fall into the following",;
        "categories:",;
        "",;
        "    Function Keys",;
        "        Keys that execute debugger functions",;
        "",;
        "    Window keys",;
        "        Keys that operate on the active window",;
        "",;
        "    Others",;
        "        Keys for window navigation and sizing",;
        "",;
        "",;
        "Other keys (typeable characters) are sent to",;
        "the Command window and treated as input text." }

   aTopics[ 3 ][ 2 ] := ;
      { "F1     Help",;
        "F2     Zoom active window",;
        "",;
        "F3     Retype last command",;
        "F4     View Application (User) screen",;
        "",;
        "F5     Go (Run application)",;
        "F6     View Workareas screen",;
        "",;
        "F7     Run to cursor line",;
        "F8     Step",;
        "",;
        "F9     Set breakpoint on cursor line",;
        "F10    Trace" }

   aTopics[ 4 ][ 2 ] := ;
      { "Enter        If input is pending in the Command window,",;
        "              will execute the command, regardless",;
        "             of which window is active. Otherwise, if the",;
        "             Monitor or Watch window is active, ENTER will",;
        "             inspect the selected window item.",;
        "",;
        "Up           In Code window, moves cursor line up.",;
        "             In Command window, recalls previous command.",;
        "             In other windows, moves selected item up.",;
        "",;
        "Down         In Code window, moves cursor line down.",;
        "             In Command window, recalls previous command.",;
        "             In other windows, moves selected item down.",;
        "",;
        "PageUp       In Code window, pages source up.",;
        "             In Command window, does nothing.",;
        "             In other windows, pages item list up.",;
        "",;
        "PageDn       In Code window, pages source down.",;
        "             In Command window, does nothing.",;
        "             In other windows, pages item list down.",;
        "",;
        "Ctrl PageUp  In Code window, moves cursor line to top.",;
        "             of source.",;
        "             In Command window, does nothing.",;
        "             In other windows, selects first item on list.",;
        "",;
        "Ctrl PageDn  In Code window, moves cursor line to bottom.",;
        "             of source.",;
        "             In Command window, does nothing",;
        "             In other windows, selects last item on list.",;
        "",;
        "Left         In Code window, scrolls left 1 column.",;
        "             In Command window, moves cursor left.",;
        "             In other windows, does nothing",;
        "",;
        "Right        In Code window, scrolls right 1 column.",;
        "             In Command window, moves cursor right.",;
        "             In other windows, does nothing.",;
        "",;
        "Home         In Code window, scrolls hard left.",;
        "             In Command window, moves cursor to beginning",;
        "             of line.",;
        "             In other windows, does nothing.",;
        "",;
        "End          In Code window, scrolls hard right.",;
        "             In Command window, moves cursor to end",;
        "             of line.",;
        "             In other windows, does nothing.",;
        "",;
        "Esc          In Command window, clears command line.",;
        "             In other windows, does nothing." }

   aTopics[ 5 ][ 2 ] := ;
      { "TAB         Next window",;
        "",;
        "SHIFT-TAB   Previous window",;
        "",;
        "ALT-G       Grow active window",;
        "",;
        "ALT-S       Shrink active window",;
        "",;
        "ALT-U       Move the border between Command and Code",;
        "            windows Up",;
        "",;
        "ALT-D       Move the border between Command and Code",;
        "            windows Down",;
        "",;
        "ALT-X       Exit" }

   aTopics[ 6 ][ 2 ] := ;
      { "The Debugger display consists of the following five",;
        "windows:",;
        "",;
        "    Command Window",;
        "        Accepts and displays debugger commands.",;
        "        Always open.",;
        "",;
        "    Code Window",;
        "        Displays program source code.",;
        "        Always open.",;
        "",;
        "    Watch Window",;
        "        Displays Watchpoints and Tracepoints, and inspects",;
        "        their values.",;
        "        Open when any Watchpoints or Tracepoints are",;
        "        defined. These are set and deleted via the",;
        "        Point menu.",;
        "",;
        "    Monitor Window",;
        "        Displays monitored variables, and inspects their",;
        "        values.",;
        "        Open when any classes of variables are being",;
        "        monitored, via commands in the Monitor menu.",;
        "",;
        "    CallStack Window",;
        "        Displays program call stack.",;
        "        Opened via the View:CallStack menu option.",;
        "",;
        "        If this window is active, the Code, Watch and",;
        "        Monitor windows will display information pertaining",;
        "        to the selected call on the CallStack.",;
        "",;
        "",;
        "One debugger window is active at a time. The active window",;
        "is displayed with a hilighted border. TAB and SHIFT-TAB",;
        "navigate among open windows.",;
        "",;
        "The Window menu contains options to Move, Size, Zoom and",;
        "Iconize the active window.",;
        "",;
        "After a long session of moving and sizing, the Window:Tile",;
        "menu option will restore the windows to their original",;
        "size and location." }

   aTopics[ 7 ][ 2 ] := ;
      { "The Command window accepts debugger commands as line",;
        "input, and displays the response from an executed",;
        "command, if any.",;
        "",;
        "Commands are entered simply by typing in the command",;
        "text, then pressing ENTER.",;
        "",;
        "Commands may be entered and executed while any",;
        "window is active. However, the entry cursor is",;
        "only visible within the Command window when it is",;
        "active.",;
        "",;
        "When the Command window is active, the UP and DOWN",;
        "arrow keys can be used to recall previous commands." }

   aTopics[ 8 ][ 2 ] := ;
      { "The Code window displays Clipper source code for",;
        "the program being debugged.",;
        "",;
        "",;
        "What file the Code window displays may be controlled",;
        "in the following ways:",;
        "",;
        "    1.  By default, the Code window will contain the line",;
        "        of Clipper code currently being executed.",;
        "",;
        "    2.  If the CallStack window is open, the code being",;
        "        viewed is that of the selected call in the CallStack",;
        "        window.",;
        "",;
        "        NOTE: By default this will be the same code as 1,",;
        "        but code for the other calls may be viewed by",;
        "        making the CallStack window active and using UP",;
        "        and DOWN to traverse the call stack.",;
        "",;
        "    3.  A specific file may be viewed by issuing a VIEW",;
        "        command, or selecting the File:View menu option.",;
        "",;
        "",;
        "If the Code window contains the line of Clipper code",;
        "currently being executed, that line will be hilighted.",;
        "Any lines which have Breakpoints set on them will also",;
        "be marked.",;
        "",;
        "",;
        "In addition to standard navigation keys, you can search",;
        "the viewed file for a specific string, or go to a particular",;
        "line within it, using options found in the Locate menu." }

   aTopics[ 9 ][ 2 ] := ;
      { "The Watch window displays Watchpoint and Tracepoint",;
        "expressions, and their current values.",;
        "",;
        "Watchpoints and Tracepoints may be defined and deleted via",;
        "options on the Point menu. You can edit a Watchpoint or",;
        "Tracepoint expression by selecting it in the Watch window",;
        "and pressing CTRL-ENTER.",;
        "",;
        "If the Watch window is active, pressing ENTER will inspect",;
        "the value of the selected expression. The navigation keys",;
        "described in 'Window Keys' may be used to change the",;
        "selected item.",;
        "",;
        "If the CallStack window is active, the Watch window will",;
        "display the values for Watchpoints and Tracepoints at the",;
        "activation level represented by the selected call in the",;
        "CallStack window." }

   aTopics[ 10 ][ 2 ] := ;
      { "The Monitor window displays monitored variables.",;
        "",;
        "Classes of variables may be monitored via options in the",;
        "Monitor menu.",;
        "",;
        "If the Monitor window is active, pressing ENTER will",;
        "inspect the value of the selected variable. The navigation",;
        "keys described in 'Window Keys' may be used to change the",;
        "selected item.",;
        "",;
        "If the CallStack window is active, the Monitor window will",;
        "display the values of variables at the point of the",;
        "activation level represented by the selected call in the",;
        "CallStack window." }

   aTopics[ 11 ][ 2 ] := ;
      { "The CallStack window displays the program's call stack.",;
        "It is opened and closed via the View:CallStack menu",;
        "option.",;
        "",;
        "By default, the selected call within the CallStack window",;
        "is the top one -- i.e., the call currently being executed.",;
        "When the CallStack window is active, the other call levels",;
        "may be selected using the navigation keys described in",;
        "'Window Keys'.",;
        "",;
        "All other windows except the Command window are synchronized",;
        "with the CallStack window. The code viewed in the Code",;
        "window, the values of Watchpoints and Tracepoints in the",;
        "Watch window, and the values of variables in the Monitor",;
        "window are all in the context of the activation level",;
        "selected in the CallStack window." }

   aTopics[ 12 ][ 2 ] := ;
      { "The debugger menus contain various debugger functions.",;
        "",;
        "Each menu may be accessed at any time by pressing the",;
        "ALT key, and the first letter in the menu's name.",;
        "",;
        "Once in a menu, the UP and DOWN arrow keys navigate",;
        "the list of options. An option may be selected by",;
        "pressing ENTER, or by typing the first uppercase",;
        "letter within the name of the desired option.",;
        "",;
        "",;
        "Some menu options toggle a debugger setting. These",;
        "options will have a checkmark displayed to their left",;
        "if the setting they refer to is currently ON.",;
        "",;
        "",;
        "Each menu option is also available as a command,",;
        "made up of the Menu name, followed by the first",;
        "word of the option name. For instance, the",;
        "View:CallStack menu option may also be accessed via",;
        "the command:",;
        "",;
        "    View Call",;
        "",;
        "Words within these commands may be shortened in most",;
        "cases to one letter.",;
        "",;
        "For more information on this class of commands, see",;
        "the 'Commands' section of this help." }

   aTopics[ 13 ][ 2 ] := ;
      { "Options:",;
        "",;
        "    Open...",;
        "    Specify a file to be opened in the Code window",;
        "",;
        "    DOS Access",;
        "    Shell to the DOS environment",;
        "",;
        "    Exit    Alt-X",;
        "    Exit the debugger" }

   aTopics[ 14 ][ 2 ] := ;
      { "Facilites for navigating the file in the Code window",;
        "",;
        "Options:",;
        "",;
        "    Find...",;
        "    Search for a specified string, from the beginning",;
        "    of the file onward.",;
        "",;
        "    Next",;
        "    Search for the next occurence of the Find string,",;
        "    from the cursor line onward.",;
        "",;
        "    Prev",;
        "    Search for the previous occurence of the Find string,",;
        "    from the cursor line backward.",;
        "",;
        "    Goto Line...",;
        "    Go to a specific line in the file being viewed.",;
        "",;
        "    Case Sensitivity",;
        "    Toggles case sensitivity in searches. Default is",;
        "    OFF." }

   aTopics[ 15 ][ 2 ] := ;
      { "Options:",;
        "",;
        "    Sets",;
        "    View Set status information",;
        "",;
        "    Work Areas   F6",;
        "    View Database status information",;
        "",;
        "    App. screen  F4",;
        "    Displays application screen, until key is pressed",;
        "",;
        "    CallStack",;
        "    Toggles the CallStack window. Default is OFF" }

   aTopics[ 16 ][ 2 ] := ;
      { "Options:",;
        "",;
        "    Restart",;
        "    Terminate program and re-execute, leaving debugger",;
        "    settings in place",;
        "",;
        "    Animate",;
        "    Execute program in Animate mode",;
        "",;
        "    Step              F8",;
        "    Execute one line of program code",;
        "",;
        "    Trace            F10",;
        "    Trace over function call in program code",;
        "",;
        "    Go                F5",;
        "    Execute program",;
        "",;
        "    to Cursor         F7",;
        "    Execute program, breaking at the current cursor",;
        "    line in Code window",;
        "",;
        "    Next routine Ctrl-F5",;
        "    Execute program, breaking at line 1 of the next",;
        "    procedure or function call.,",;
        "",;
        "    sPeed...",;
        "    Set step speed for Animate mode execution" }

   aTopics[ 17 ][ 2 ] := ;
      { "Options:",;
        "",;
        "    Watchpoint...",;
        "",;
        "    Add Watchpoint. A Watchpoint is an expression which",;
        "    the debugger tracks during program execution -- the",;
        "    current value of a Watchpoint is displayed in the",;
        "    Watch window during debugging.",;
        "",;
        "    A Watchpoint may be any valid Clipper expression,",;
        "    i.e.:",;
        "",;
        "        s                   // variable",;
        "        a[n]                // array element",;
        "        g:buffer            // object instance variable",;
        "        At(s, t)            // return value of function call",;
        "        ValType(s) == 'C'   // value of expression",;
        "",;
        "",;
        "    Tracepoint...",;
        "",;
        "    Add Tracepoint. A Tracepoint is similar to a Watchpoint,",;
        "    with the additional property that if the value of a",;
        "    Tracepoint expression changes, the debugger will be",;
        "    invoked as if a Breakpoint had been hit.",;
        "",;
        "",;
        "    Breakpoint   F9",;
        "",;
        "    Set Breakpoint on current cursor line in",;
        "    Code window",;
        "",;
        "",;
        "    Delete",;
        "",;
        "    Delete Tracepoint or Watchpoint." }

   aTopics[ 18 ][ 2 ] := ;
      { "Options:",;
        "",;
        "    Public",;
        "    Monitor Public variables.",;
        "",;
        "    Private",;
        "    Monitor Private variables.",;
        "",;
        "    Local",;
        "    Monitor Local variables.",;
        "",;
        "    Static",;
        "    Monitor Static variables.",;
        "",;
        "    Global",;
        "    Monitor Global variables.",;
        "",;
        "    All",;
        "    Monitor All variables.",;
        "",;
        "    Sort",;
        "    Toggles whether monitored variables are sorted by",;
        "    name. Default is OFF." }

   aTopics[ 19 ][ 2 ] := ;
      { "Options:",;
        "",;
        "    Preprocessed code",;
        "    Toggles the display of preprocessed code (from",;
        "    PPO file) within the Code window. Default is OFF.",;
        "",;
        "    Line numbers",;
        "    Toggles the display of line numbers in the Code",;
        "    window. Default is OFF.",;
        "",;
        "    Exchange screens",;
        "    Toggles whether debugger screen is swapped with",;
        "    application screen during debugger execution.",;
        "    Default is ON.",;
        "",;
        "    Swap on Input",;
        "    Toggles whether debugger screen is swapped with",;
        "    application screen when the program being debugged",;
        "    is waiting for input. Default is ON.",;
        "    This setting is only meaningful when the Exchange",;
        "    Screens setting is OFF.",;
        "",;
        "    Codeblock Trace",;
        "    Toggles whether the debugger will trace into",;
        "    code blocks when tracing (i.e., when in Trace",;
        "    mode). Defaults to ON.",;
        "",;
        "    Menu Bar",;
        "    Toggles display of the debugger menu bar.",;
        "    Default is ON.",;
        "",;
        "    mono Display",;
        "    Toggles display between monochrome and color.",;
        "    Default is OFF.",;
        "",;
        "    Colors...",;
        "    Inspects debugger colors.",;
        "",;
        "    Tab width...",;
        "    Set tab width in Code window. Default is 4.",;
        "",;
        "    pAth for Files...",;
        "    Specify search path for source files.",;
        "    The debugger will use this path to search for",;
        "    files, if not found in the current directory.",;
        "    NOTE: If not found in the debugger path, the",;
        "    directories specified in the environment's PATH",;
        "    will be searched.",;
        "",;
        "",;
        "    Save Settings",;
        "    Save debugger settings to a script file.",;
        "",;
        "    Restore Settings",;
        "    Restore debugger settings from a previously",;
        "    saved script file." }

   aTopics[ 20 ][ 2 ] := ;
      { "Options:",;
        "",;
        "    Next       Tab",;
        "    Make next window active.",;
        "",;
        "    Prev    Sh-Tab",;
        "    Make previous window active.",;
        "",;
        "    Move",;
        "    Move active window. UP, DOWN, LEFT, RIGHT,",;
        "    PGUP, PGDN, HOME, END move ENTER finishes,",;
        "    While Moving, top left corner of window is marked.",;
        "",;
        "    Size",;
        "    Size active window. UP, DOWN, LEFT, RIGHT,",;
        "    PGUP, PGDN, HOME, END size ENTER finishes,",;
        "    While Sizing, bottom right corner of window is marked.",;
        "",;
        "    Zoom        F2",;
        "    Toggles whether active window is Zoomed. When",;
        "    Zoomed, window will fill entire display area.",;
        "",;
        "    Iconize",;
        "    Toggles whether active window is Iconized. When",;
        "    Iconized, window will be one row high and a few",;
        "    columns wide.",;
        "",;
        "    Tile",;
        "    Restore all windows to original size and position." }

   aTopics[ 21 ][ 2 ] := ;
      { "There are two sets of debugger commands:",;
        "",;
        "1. Menu option commands. These commands are formed",;
        "from the menu name, followed by the (first word of)",;
        "the option name. For instance, the Monitor:Public",;
        "menu option may be invoked via the command:",;
        "",;
        "    Monitor Public",;
        "",;
        "These commands may be abbreviated down to one letter",;
        "per word. However in some cases a second letter will",;
        "be required in the second word, as in the case of",;
        "Monitor Private:",;
        "",;
        "    M P     // invokes Monitor Public",;
        "    M Pr    // invokes Monitor Private",;
        "",;
        "",;
        "",;
        "2. Other commands. Listed below.",;
        "",;
        "",;
        "? ",;
        "    Display the value of a variable or expression.",;
        "",;
        "?? ",;
        "    Inspect the value of a variable or expression.",;
        "",;
        "ANIMATE",;
        "    Execute application in Animate Mode.",;
        "",;
        "BP [ [  ]]|[]",;
        "",;
        "   BP",;
        "      Toggle breakpoint at current line in current",;
        "      source file.",;
        "",;
        "   BP ",;
        "      Toggle breakpoint at  in current source",;
        "      file.",;
        "",;
        "   BP  ",;
        "      Toggle breakpoint at  in ",;
        "      source file.",;
        "   BP ",;
        "     Toggle breakpoint on function.",;
        "",;
        "CALLSTACK on|OFF",;
        "    Toggle display of CallStack window",;
        "",;
        "DELETE ALL [WP|TP|BP]",;
        "DELETE WP|TP|BP ",;
        "    Delete all or particular Watchpoint, Tracepoint",;
        "    or Breakpoint.",;
        "",;
        "DOS",;
        "    Visit the operating system.",;
        "",;
        "FIND ",;
        "    Search currently viewed file for specified",;
        "    character string.",;
        "",;
        "GO",;
        "    Execute application in Run Mode.",;
        "",;
        "GOTO ",;
        "    Move cursor to specified line in currently viewed",;
        "    file.",;
        "",;
        "HELP",;
        "    Get advice in the form of the Help window.",;
        "",;
        "INPUT ",;
        "    Read commands from specified Script File.",;
        "",;
        "LIST BP|WP|TP",;
        "    List Breakpoints, Watchpoints or Tracepoints in",;
        "    the Command Window.",;
        "",;
        "NEXT",;
        "    Search for next occurence of FIND string.",;
        "",;
        "NUM ON|off",;
        "    Toggle display of line numbers in Code window.",;
        "",;
        "OUTPUT",;
        "    View application screen.",;
        "",;
        "",;
        "PREV",;
        "    Search for previous occurence of FIND string.",;
        "",;
        "QUIT",;
        "    Quit.",;
        "",;
        "RESTART",;
        "    Restart application",;
        "",;
        "RESUME",;
        "    Resume viewing the currently executing program",;
        "    code in the Code Window, after VIEWing another",;
        "    file.",;
        "",;
        "SPEED ",;
        "    Set Animate mode step speed.  designates",;
        "    the number of tenths of a second to delay.",;
        "     must be greater than or equal to 0.",;
        "",;
        "STEP",;
        "    Execute one line of program code.",;
        "",;
        "TP ",;
        "    Establish  as a Tracepoint.  may be a",;
        "    variable or expression.",;
        "",;
        "VIEW ",;
        "   View specified file in Code window.",;
        "",;
        "WP ",;
        "    Establish  as a Watchpoint.  may be a",;
        "    variable or expression." }

   aTopics[ 22 ][ 2 ] := ;
      { "Script files contain debugger commands, in the same",;
        "form they would take as input in the Command window.",;
        "By default, script files use the extension CLD, as in",;
        "'myscript.cld'.",;
        "",;
        "",;
        "Creating a script file:",;
        "",;
        "A script file containing all the debugger's current",;
        "settings may be created via the Options:Save menu",;
        "option. A script file may also be written by hand,",;
        "in a text editor.",;
        "",;
        "",;
        "Reading a script file:",;
        "",;
        "A script file may be read into the debugger at any",;
        "time using the Options:Restore menu option.",;
        "",;
        "When using CLD.EXE, a script file may also be",;
        "specified on the command line, before the name of",;
        "the program to be debugged, i.e.:",;
        "",;
        "    CLD @ ",;
        "",;
        "In both of these, the extension '.cld' will be assumed",;
        "if no extension is supplied.",;
        "",;
        "When reading a script file, the debugger will look",;
        "for the file in the current directory first. If the",;
        "script is not found there, the debugger will search",;
        "all directories in the PATH environment variable.",;
        "",;
        "",;
        "init.cld:",;
        "",;
        "On startup (or, if it is linked into a program, when",;
        "it is first invoked), the debugger will look for a",;
        "script file called init.cld, in the current directory",;
        "and then, if not found, in the directories specified",;
        "by the PATH environment variable.",;
        "",;
        "If init.cld is found, the debugger will read it",;
        "automatically. It is useful to place general",;
        "preferences in init.cld -- specifying colors,",;
        "turning on the CallStack window, and so on." }

   RETURN aTopics
dbghelp.prg234
dbgmenu.prg
TypeFunctionSourceLine
FUNCTION__dbgBuildMenu( oDebugger )
FUNCTION __dbgBuildMenu( oDebugger )  // Builds the debugger pulldown menu

   LOCAL oMenu

   MENU oMenu
      MENUITEM " ~File "
      MENU
         MENUITEM " ~Open..."         ACTION oDebugger:Open()
         MENUITEM " ~Resume"          ACTION oDebugger:Resume()
         MENUITEM " O~S Shell"        ACTION oDebugger:OSShell()
         SEPARATOR
         MENUITEM " e~Xit    Alt-X "  ACTION oDebugger:Quit()
      ENDMENU

      MENUITEM " ~Locate "
      MENU
         MENUITEM " ~Find"            ACTION oDebugger:Locate()
         MENUITEM " ~Next"            ACTION oDebugger:FindNext()
         MENUITEM " ~Previous"        ACTION oDebugger:FindPrevious()
         MENUITEM " ~Goto line..."    ACTION oDebugger:SearchLine()
         SEPARATOR
         MENUITEM " ~Case sensitive " IDENT "CASE" ;
            ACTION oDebugger:ToggleCaseSensitive() ;
            CHECKED oDebugger:lCaseSensitive
      ENDMENU

      MENUITEM " ~View "
      MENU
         MENUITEM " ~Sets"            ACTION oDebugger:ViewSets()
         MENUITEM " ~WorkAreas   F6"  ACTION oDebugger:ShowWorkAreas()
         MENUITEM " ~App Screen  F4 " ACTION oDebugger:ShowAppScreen()
         SEPARATOR
         MENUITEM " ~CallStack" IDENT "CALLSTACK";
            ACTION oDebugger:Stack() ;
            CHECKED oDebugger:lShowCallStack
      ENDMENU

      MENUITEM " ~Run "
      MENU
         MENUITEM " ~Animate" IDENT "ANIMATE" ;
            ACTION ( oDebugger:ToggleAnimate(), oDebugger:Animate() ) ;
            CHECKED oDebugger:lAnimate
         MENUITEM " ~Step              F8 " ACTION oDebugger:Step()
         MENUITEM " ~Trace            F10"  ACTION oDebugger:Trace()
         MENUITEM " ~Go                F5"  ACTION oDebugger:Go()
         MENUITEM " to ~Cursor         F7"  ACTION oDebugger:ToCursor()
         MENUITEM " ~Next routine Ctrl-F5"  ACTION oDebugger:NextRoutine()
         SEPARATOR
         MENUITEM " s~Peed..."              ACTION oDebugger:Speed()
      ENDMENU

      MENUITEM " ~Point "
      MENU
         MENUITEM " ~Watchpoint..."         ACTION oDebugger:WatchPointAdd()
         MENUITEM " ~Tracepoint..."         ACTION oDebugger:TracePointAdd()
         MENUITEM " ~Breakpoint   F9 "      ACTION oDebugger:ToggleBreakPoint()
         MENUITEM " ~Delete..."             ACTION oDebugger:WatchPointDel()
      ENDMENU

      MENUITEM " ~Monitor "
      MENU
         MENUITEM " ~Public" IDENT "PUBLIC" ;
            ACTION oDebugger:Public() ;
            CHECKED oDebugger:lShowPublics

         MENUITEM " pri~Vate " IDENT "PRIVATE" ;
            ACTION oDebugger:Private() ;
            CHECKED oDebugger:lShowPrivates
            
         MENUITEM " ~Static" IDENT "STATIC" ;
            ACTION oDebugger:Static() ;
            CHECKED oDebugger:lShowStatics
           
         MENUITEM " ~Local" IDENT "LOCAL" ;
            ACTION oDebugger:Local() ;
            CHECKED oDebugger:lShowLocals
            
         MENUITEM " ~Global" IDENT "GLOBAL" ;
            ACTION oDebugger:Global() ;
            CHECKED oDebugger:lShowGlobals

         SEPARATOR
         
         MENUITEM " ~All" IDENT "ALL" ;
            ACTION oDebugger:All() ;
            CHECKED oDebugger:lAll

         MENUITEM " S~how all Globals" IDENT "SHOWALLGLOBALS" ;
            ACTION oDebugger:ShowAllGlobals() ;
            CHECKED oDebugger:lShowAllGlobals

         MENUITEM " s~Ort" ACTION oDebugger:Sort()
      ENDMENU

      MENUITEM " ~Options "
      MENU
         MENUITEM " ~Preprocessed Code" IDENT "PPO" ;
            ACTION oDebugger:OpenPPO() ;
            CHECKED oDebugger:lPPO
         MENUITEM " ~Line Numbers" IDENT "LINE" ;
            ACTION oDebugger:LineNumbers() ;
            CHECKED oDebugger:lLineNumbers
         MENUITEM " ~Exchange Screens"      ACTION oDebugger:NotSupported()
         MENUITEM " swap on ~Input"         ACTION oDebugger:NotSupported()
         MENUITEM " code~Block Trace" IDENT "CODEBLOCK" ;
            ACTION oDebugger:CodeblockTrace() ;
            CHECKED oDebugger:lCBTrace
         MENUITEM " ~Menu Bar"              ACTION oDebugger:NotSupported()
         MENUITEM " mono ~Display" IDENT "MONO";
            ACTION oDebugger:MonoDisplay() ;
            CHECKED oDebugger:lMonoDisplay
         MENUITEM " ~Colors..."             ACTION oDebugger:Colors()
         MENUITEM " ~Tab Width..."          ACTION oDebugger:TabWidth()
         MENUITEM " path for ~Files..."     ACTION oDebugger:PathForFiles()
         MENUITEM " R~un at startup" IDENT "ALTD" ;
            ACTION oDebugger:RunAtStartup() ;
            CHECKED oDebugger:lRunAtStartup
         SEPARATOR
         MENUITEM " ~Save Settings..."      ACTION oDebugger:SaveSettings()
         MENUITEM " ~Restore Settings... "  ACTION oDebugger:RestoreSettings()
      ENDMENU

      MENUITEM " ~Window "
      MENU
         MENUITEM " ~Next      Tab "        ACTION oDebugger:NextWindow()
         MENUITEM " ~Prev   Sh-Tab"         ACTION oDebugger:PrevWindow()
         MENUITEM " ~Move"                  ACTION oDebugger:NotSupported()
         MENUITEM " ~Size"                  ACTION oDebugger:NotSupported()
         MENUITEM " ~Zoom       F2"         ACTION oDebugger:NotSupported()
         MENUITEM " ~Iconize"               ACTION oDebugger:NotSupported()
         SEPARATOR
         MENUITEM " ~Tile"                  ACTION oDebugger:NotSupported()
      ENDMENU

      MENUITEM " ~Help "
      MENU
         MENUITEM " ~About Help "           ACTION oDebugger:ShowHelp( 0 )
         SEPARATOR
         MENUITEM " ~Keys"                  ACTION oDebugger:ShowHelp( 2 )
         MENUITEM " ~Windows"               ACTION oDebugger:ShowHelp( 6 )
         MENUITEM " ~Menus"                 ACTION oDebugger:ShowHelp( 12 )
         MENUITEM " ~Commands"              ACTION oDebugger:ShowHelp( 21 )
      ENDMENU

   ENDMENU

   RETURN oMenu
dbgmenu.prg64
dbgtarr.prg
TypeFunctionSourceLine
METHODNew( aArray, cVarName, lEditable )
   METHOD New( aArray, cVarName, lEditable )
dbgtarr.prg67
METHODaddWindows( aArray, nRow )
   METHOD addWindows( aArray, nRow )
dbgtarr.prg69
METHODdoGet( oBrowse, pItem, nSet )
   METHOD doGet( oBrowse, pItem, nSet )
dbgtarr.prg70
METHODSetsKeyPressed( nKey, oBrwSets, oWnd, cName, aArray )
   METHOD SetsKeyPressed( nKey, oBrwSets, oWnd, cName, aArray )

ENDCLASS
dbgtarr.prg71
HBDBARRAY:METHODNew( aArray, cVarName, lEditable ) CLASS HBDbArray
METHOD New( aArray, cVarName, lEditable ) CLASS HBDbArray

   DEFAULT lEditable TO .T.

   ::arrayName := cVarName
   ::TheArray := aArray
   ::lEditable := lEditable

   ::addWindows( ::TheArray )

   RETURN Self
dbgtarr.prg75
HBDBARRAY:METHODaddWindows( aArray, nRow ) CLASS HBDbArray
METHOD addWindows( aArray, nRow ) CLASS HBDbArray
   LOCAL oBrwSets
   LOCAL nSize := Len( aArray )
   LOCAL oWndSets
   LOCAL nWidth
   LOCAL nColWidth
   LOCAL oCol

   IF nSize < MaxRow() - 2
      IF nRow != NIL
         oWndSets := HBDbWindow():New( GetTopPos( nRow ), 5, getBottomPos( nRow + nSize + 1 ), MaxCol() - 5, ::arrayName + "[1.." + LTrim( Str( nSize, 6 ) ) + "]", "N/W" )
      ELSE
         oWndSets := HBDbWindow():New( 1, 5, 2 + nSize, MaxCol() - 5, ::arrayName + "[1.." + LTrim( Str( nSize, 6 ) ) + "]", "N/W" )
      ENDIF
   ELSE
      oWndSets := HBDbWindow():New( 1, 5, MaxRow() - 2, MaxCol() - 5, ::arrayName + "[1.." + LTrim( Str( nSize, 6 ) ) + "]", "N/W" )
   ENDIF

   ::nCurWindow++
   oWndSets:lFocused := .T.
   AAdd( ::aWindows, oWndSets )

   nWidth := oWndSets:nRight - oWndSets:nLeft - 1
   oBrwSets := HBDbBrowser():New( oWndSets:nTop + 1, oWndSets:nLeft + 1, oWndSets:nBottom - 1, oWndSets:nRight - 1 )
   oBrwSets:autolite := .F.
   oBrwSets:ColorSpec := __Dbg():ClrModal()
   oBrwSets:Cargo := { 1, {} } // Actual highligthed row
   AAdd( oBrwSets:Cargo[ 2 ], aArray )

   oBrwSets:AddColumn( oCol := TBColumnNew( "", { || ::arrayName + "[" + LTrim( Str( oBrwSets:cargo[ 1 ], 6 ) ) + "]" } ) )
   oCol:width := Len( ::arrayName + "[" + LTrim( Str( Len( aArray ), 6 ) ) + "]" )
   oCol:DefColor := { 1, 2 }
   nColWidth := oCol:Width

   oBrwSets:AddColumn( oCol := TBColumnNew( "", { || PadR( __dbgValToStr( aArray[ oBrwSets:cargo[ 1 ] ] ), nWidth - nColWidth - 1 ) } ) )

   /* 09/08/2004 - 
                   Setting a fixed width like it is done in the next line of code wich I've
                   commented exploits a bug of current tbrowse, that is, if every column is
                   narrower than tbrowse but the sum of them is wider tbrowse paints
                   one above the other if code like the one inside RefreshVarsS() is called.
                   (That code is used to have current row fully highlighted and not only
                   current cell). Reproducing this situation on a smaller sample with
                   clipper causes that only column two is visible after first stabilization.

                   I think tbrowse should trim columns up until the point where at leat
                   two are visible in the same moment, I leave this fix to tbrowse for
                   the reader ;)
   oCol:width := 50
   */

   oCol:defColor := { 1, 3 }

   oBrwSets:goTopBlock := { || oBrwSets:cargo[ 1 ] := 1 }
   oBrwSets:goBottomBlock := { || oBrwSets:cargo[ 1 ] := Len( oBrwSets:cargo[ 2 ][ 1 ] ) }
   oBrwSets:skipBlock := { | nPos | ( nPos := ArrayBrowseSkip( nPos, oBrwSets ), oBrwSets:cargo[ 1 ] := ;
                                    oBrwSets:cargo[ 1 ] + nPos, nPos ) }

   ::aWindows[ ::nCurWindow ]:bPainted    := { || ( oBrwSets:forcestable(), RefreshVarsS( oBrwSets ) ) }
   ::aWindows[ ::nCurWindow ]:bKeyPressed := { | nKey | ::SetsKeyPressed( nKey, oBrwSets,;
                           ::aWindows[ ::nCurWindow ], ::arrayName, aArray ) }

   SetCursor( SC_NONE )

   ::aWindows[ ::nCurWindow ]:ShowModal()

   RETURN Self
dbgtarr.prg87
HBDBARRAY:METHODdoGet( oBrowse, pItem, nSet ) CLASS HBDbArray
METHOD doGet( oBrowse, pItem, nSet ) CLASS HBDbArray

#ifndef HB_NO_READDBG

   LOCAL nKey
   LOCAL oErr
   LOCAL GetList := {}
   LOCAL lScoreSave := Set( _SET_SCOREBOARD, .F. )
   LOCAL lExitSave  := Set( _SET_EXIT, .T. )
   LOCAL bInsSave   := SetKey( K_INS )
   LOCAL cValue     := PadR( __dbgValToStr( pItem[ nSet ] ),;
                             oBrowse:nRight - oBrowse:nLeft - oBrowse:GetColumn( 1 ):width )

   // make sure browse is stable
   oBrowse:forceStable()
   // if confirming new record, append blank

   // set insert key to toggle insert mode and cursor
   SetKey( K_INS, { || SetCursor( iif( ReadInsert( ! ReadInsert() ),;
           SC_NORMAL, SC_INSERT ) ) } )

   // initial cursor setting
   SetCursor( iif( ReadInsert(), SC_INSERT, SC_NORMAL ) )

   // create a corresponding GET
   @ Row(), oBrowse:nLeft + oBrowse:GetColumn( 1 ):width + 1 GET cValue ;
      VALID iif( Type( cValue ) == "UE", ( Alert( "Expression error" ), .F. ), .T. )

   READ

   IF LastKey() == K_ENTER
      BEGIN SEQUENCE WITH {|oErr| break( oErr ) }
         pItem[ nSet ] := &cValue
      RECOVER USING oErr
         Alert( oErr:description )
      END SEQUENCE
   ENDIF

   SetCursor( SC_NONE )
   Set( _SET_SCOREBOARD, lScoreSave )
   Set( _SET_EXIT, lExitSave )
   SetKey( K_INS, bInsSave )

   // check exit key from get
   nKey := LastKey()
   IF nKey == K_UP .OR. nKey == K_DOWN .OR. nKey == K_PGUP .OR. nKey == K_PGDN
      KEYBOARD Chr( nKey )
   ENDIF

#else

   HB_SYMBOL_UNUSED( oBrowse )
   HB_SYMBOL_UNUSED( pItem )
   HB_SYMBOL_UNUSED( nSet )

#endif

   RETURN NIL
dbgtarr.prg155
HBDBARRAY:METHODSetsKeyPressed( nKey, oBrwSets, oWnd, cName, aArray ) CLASS HBDbArray
METHOD SetsKeyPressed( nKey, oBrwSets, oWnd, cName, aArray ) CLASS HBDbArray

   LOCAL nSet := oBrwSets:cargo[ 1 ]
   LOCAL cOldName := ::arrayName

   DO CASE
   CASE nKey == K_UP
      oBrwSets:Up()

   CASE nKey == K_DOWN
      oBrwSets:Down()

   CASE nKey == K_HOME .OR. nKey == K_CTRL_PGUP .OR. nKey == K_CTRL_HOME
      oBrwSets:GoTop()

   CASE nKey == K_END .OR. nKey == K_CTRL_PGDN .OR. nKey == K_CTRL_END
      oBrwSets:GoBottom()

   CASE nKey == K_PGDN
      oBrwSets:pageDown()

   CASE nKey == K_PGUP
      oBrwSets:PageUp()

   CASE nKey == K_ENTER
      IF ISARRAY( aArray[ nSet ] )
         IF Len( aArray[ nSet ] ) == 0
            Alert( "Array is empty" )
         ELSE
            SetPos( oWnd:nBottom, oWnd:nLeft )
            ::aWindows[ ::nCurWindow ]:lFocused := .F.
            ::arrayname := ::arrayname + "[" + LTrim( Str( nSet, 4 ) ) + "]"
            ::AddWindows( aArray[ nSet ], oBrwSets:RowPos + oBrwSets:nTop )
            ::arrayname := cOldName

            ADel( ::aWindows, ::nCurWindow )
            ASize( ::aWindows, Len( ::aWindows ) - 1 )
            IF ::nCurWindow == 0
               ::nCurWindow := 1
            ELSE
               ::nCurWindow--
            ENDIF
         ENDIF
      ELSEIF ISBLOCK( aArray[ nSet ] ) .OR. Valtype( aArray[ nSet ] ) == "P"
         Alert( "Value cannot be edited" )
      ELSE
         IF ::lEditable
            oBrwSets:RefreshCurrent()
            IF ISOBJECT( aArray[ nSet ] )
               __DbgObject( aArray[ nSet ], cName + "[" + LTrim( Str( nSet ) ) + "]" )
            ELSEIF ValType( aArray[ nSet ] ) == "H"
               __DbgHashes( aArray[ nSet ], cName + "[" + LTrim( Str( nSet ) ) + "]" )
            ELSE
               ::doGet( oBrwsets, aArray, nSet )
            ENDIF
            oBrwSets:RefreshCurrent()
            oBrwSets:ForceStable()
         ELSE
            Alert( "Value cannot be edited" )
         ENDIF
      ENDIF

   ENDCASE

   RefreshVarsS( oBrwSets )

   ::aWindows[ ::nCurWindow ]:SetCaption( cName + "[" + LTrim( Str( oBrwSets:cargo[ 1 ] ) ) + ".." + ;
                                          LTrim( Str( Len( aArray ) ) ) + "]" )

   RETURN self
dbgtarr.prg214
FUNCTION__dbgArrays( aArray, cVarName, lEditable )
FUNCTION __dbgArrays( aArray, cVarName, lEditable )
   RETURN HBDbArray():New( aArray, cVarName, lEditable )
dbgtarr.prg285
STATIC FUNCTIONGetTopPos( nPos )
STATIC FUNCTION GetTopPos( nPos )
   RETURN iif( ( MaxRow() - nPos ) < 5, MaxRow() - nPos, nPos )
dbgtarr.prg288
STATIC FUNCTIONGetBottomPos( nPos )
STATIC FUNCTION GetBottomPos( nPos )
   RETURN iif( nPos < MaxRow() - 2, nPos, MaxRow() - 2 )
dbgtarr.prg291
STATIC PROCEDURERefreshVarsS( oBrowse )
STATIC PROCEDURE RefreshVarsS( oBrowse )

   LOCAL nLen := oBrowse:colCount

   IF nLen == 2
      oBrowse:deHilite():colPos := 2
   ENDIF
   oBrowse:deHilite():forceStable()

   IF nLen == 2
      oBrowse:hilite():colPos := 1
   ENDIF
   oBrowse:hilite()

   RETURN
dbgtarr.prg294
STATIC FUNCTIONArrayBrowseSkip( nPos, oBrwSets )
STATIC FUNCTION ArrayBrowseSkip( nPos, oBrwSets )
   RETURN iif( oBrwSets:cargo[ 1 ] + nPos < 1, 0 - oBrwSets:cargo[ 1 ] + 1 , ;
             iif( oBrwSets:cargo[ 1 ] + nPos > Len( oBrwSets:cargo[ 2 ][ 1 ] ), ;
                Len( oBrwSets:cargo[ 2 ][ 1 ] ) - oBrwSets:cargo[ 1 ], nPos ) )
dbgtarr.prg310
dbgthsh.prg
TypeFunctionSourceLine
METHODNew( hHash, cVarName, lEditable )
   METHOD New( hHash, cVarName, lEditable )
dbgthsh.prg69
METHODaddWindows( hHash, nRow )
   METHOD addWindows( hHash, nRow )
dbgthsh.prg71
METHODdoGet( oBrowse, pItem, nSet )
   METHOD doGet( oBrowse, pItem, nSet )
dbgthsh.prg72
METHODSetsKeyPressed( nKey, oBrwSets, oWnd, cName, hHash )
   METHOD SetsKeyPressed( nKey, oBrwSets, oWnd, cName, hHash )

ENDCLASS
dbgthsh.prg73
HBDBHASH:METHODNew( hHash, cVarName, lEditable ) CLASS HBDbHash
METHOD New( hHash, cVarName, lEditable ) CLASS HBDbHash

   DEFAULT lEditable TO .T.

   ::hashName := cVarName
   ::TheHash := hHash
   ::lEditable := lEditable
   
   ::addWindows( ::TheHash )

   RETURN Self
dbgthsh.prg77
HBDBHASH:METHODaddWindows( hHash, nRow ) CLASS HBDbHash
METHOD addWindows( hHash, nRow ) CLASS HBDbHash
   LOCAL oBrwSets
   LOCAL nSize := Len( hHash )
   LOCAL oWndSets
   LOCAL nWidth
   LOCAL nColWidth
   LOCAL oCol
   LOCAL nKeyLen

   IF nSize < MaxRow() - 2
      IF nRow != NIL
         oWndSets := HBDbWindow():New( GetTopPos( nRow ), 5, getBottomPos( nRow + nSize + 1 ), MaxCol() - 5, ::hashName + "[1.." + LTrim( Str( nSize, 6 ) ) + "]", "N/W" )
      ELSE
         oWndSets := HBDbWindow():New( 1, 5, 2 + nSize, MaxCol() - 5, ::hashName + "[1.." + LTrim( Str( nSize, 6 ) ) + "]", "N/W" )
      ENDIF
   ELSE
      oWndSets := HBDbWindow():New( 1, 5, MaxRow() - 2, MaxCol() - 5, ::hashName + "[1.." + LTrim( Str( nSize, 6 ) ) + "]", "N/W" )
   ENDIF
   ::nCurWindow++
   oWndSets:lFocused := .T.
   AAdd( ::aWindows, oWndSets )

   nWidth := oWndSets:nRight - oWndSets:nLeft - 1
   oBrwSets := HBDbBrowser():New( oWndSets:nTop + 1, oWndSets:nLeft + 1, oWndSets:nBottom - 1, oWndSets:nRight - 1 )
   oBrwSets:autolite := .F.
   oBrwSets:ColorSpec := __Dbg():ClrModal()
   oBrwSets:Cargo := { 1, {} } // Actual highligthed row
   AAdd( oBrwSets:Cargo[ 2 ], hHash )

   oBrwSets:AddColumn( oCol := TBColumnNew( "", { || ::hashName + "[" + HashKeyString( hHash, oBrwSets:cargo[ 1 ] ) + "]" } ) )

   // calculate max key length
   nKeyLen := 0
   hb_HEval( hHash, {| k, v, p | HB_SYMBOL_UNUSED( k ), HB_SYMBOL_UNUSED( v ), nKeyLen := Max( nKeyLen, Len( ::hashName + "[" + HashKeyString( hHash, p ) + "]" ) ) } )
   oCol:width := nKeyLen
   oCol:DefColor := { 1, 2 }
   nColWidth := oCol:Width

   oBrwSets:AddColumn( oCol := TBColumnNew( "" ,{ || PadR( __dbgValToStr( hb_HValueAt( hHash, oBrwSets:cargo[ 1 ] ) ), nWidth - nColWidth - 1 ) } ) )

   /* 09/08/2004 - 
                   Setting a fixed width like it is done in the next line of code wich I've
                   commented exploits a bug of current tbrowse, that is, if every column is
                   narrower than tbrowse but the sum of them is wider tbrowse paints
                   one above the other if code like the one inside RefreshVarsS() is called.
                   (That code is used to have current row fully highlighted and not only
                   current cell). Reproducing this situation on a smaller sample with
                   clipper causes that only column two is visible after first stabilization.

                   I think tbrowse should trim columns up until the point where at leat
                   two are visible in the same moment, I leave this fix to tbrowse for
                   the reader ;)
   oCol:width := 50
   */

   oCol:DefColor:= { 1, 3 }

   oBrwSets:goTopBlock := { || oBrwSets:cargo[ 1 ] := 1 }
   oBrwSets:goBottomBlock := { || oBrwSets:cargo[ 1 ] := Len( oBrwSets:cargo[ 2 ][ 1 ] ) }
   oBrwSets:skipBlock := { |nPos| ( nPos := HashBrowseSkip(nPos, oBrwSets), oBrwSets:cargo[ 1 ] := ;
                                    oBrwSets:cargo[ 1 ] + nPos, nPos ) }

   ::aWindows[ ::nCurWindow ]:bPainted    := { || ( oBrwSets:forcestable(), RefreshVarsS( oBrwSets ) ) }
   ::aWindows[ ::nCurWindow ]:bKeyPressed := { | nKey | ::SetsKeyPressed( nKey, oBrwSets,;
                           ::aWindows[ ::nCurWindow ],::hashName, hHash ) }

   SetCursor( SC_NONE )
   
   ::aWindows[ ::nCurWindow ]:ShowModal()

   RETURN Self
dbgthsh.prg89
HBDBHASH:METHODdoGet( oBrowse, pItem, nSet ) CLASS HBDbHash
METHOD doGet( oBrowse, pItem, nSet ) CLASS HBDbHash

#ifndef HB_NO_READDBG

   LOCAL nKey
   LOCAL oErr
   LOCAL GetList := {}
   LOCAL lScoreSave := Set( _SET_SCOREBOARD, .F. )
   LOCAL lExitSave  := Set( _SET_EXIT, .T. )
   LOCAL bInsSave   := SetKey( K_INS )
   LOCAL cValue     := PadR( __dbgValToStr( HB_HValueAt( pItem, nSet ) ),;
                             oBrowse:nRight - oBrowse:nLeft - oBrowse:GetColumn( 1 ):width )

   // make sure browse is stable
   oBrowse:forceStable()
   // if confirming new record, append blank

   // set insert key to toggle insert mode and cursor
   SetKey( K_INS, { || SetCursor( iif( ReadInsert( ! ReadInsert() ),;
           SC_NORMAL, SC_INSERT ) ) } )

   // initial cursor setting
   SetCursor( iif( ReadInsert(), SC_INSERT, SC_NORMAL ) )

   // create a corresponding GET
   @ Row(), oBrowse:nLeft + oBrowse:GetColumn( 1 ):width + 1 GET cValue ;
      VALID iif( Type( cValue ) == "UE", ( Alert( "Expression error" ), .F. ), .T. )

   READ

   IF LastKey() == K_ENTER
      BEGIN SEQUENCE WITH {|oErr| break( oErr ) }
         HB_HValueAt( pItem, nSet, &cValue )
      RECOVER USING oErr
         Alert( oErr:description )
      END SEQUENCE
   ENDIF

   SetCursor( SC_NONE )
   Set( _SET_SCOREBOARD, lScoreSave )
   Set( _SET_EXIT, lExitSave )
   SetKey( K_INS, bInsSave )

   // check exit key from get
   nKey := LastKey()
   IF nKey == K_UP .OR. nKey == K_DOWN .OR. nKey == K_PGUP .OR. nKey == K_PGDN
      KEYBOARD Chr( nKey )
   ENDIF

#else

   HB_SYMBOL_UNUSED( oBrowse )
   HB_SYMBOL_UNUSED( pItem )
   HB_SYMBOL_UNUSED( nSet )

#endif

   RETURN NIL
dbgthsh.prg161
HBDBHASH:METHODSetsKeyPressed( nKey, oBrwSets, oWnd, cName, hHash ) CLASS HBDbHash
METHOD SetsKeyPressed( nKey, oBrwSets, oWnd, cName, hHash ) CLASS HBDbHash

   LOCAL nSet := oBrwSets:cargo[ 1 ]
   LOCAL cOldname := ::hashName
   LOCAL uValue

   DO CASE
   CASE nKey == K_UP
      oBrwSets:Up()

   CASE nKey == K_DOWN
      oBrwSets:Down()

   CASE nKey == K_HOME .OR. nKey == K_CTRL_PGUP .OR. nKey == K_CTRL_HOME
      oBrwSets:GoTop()

   CASE nKey == K_END .OR. nKey == K_CTRL_PGDN .OR. nKey == K_CTRL_END
      oBrwSets:GoBottom()

   CASE nKey == K_PGDN
      oBrwSets:pageDown()

   CASE nKey == K_PGUP
      oBrwSets:PageUp()

   CASE nKey == K_ENTER

      uValue := HB_HValueAt( hHash, nSet )

      IF ValType( uValue ) == "H"

         IF Len( uValue ) == 0
            Alert( "Hash is empty" )
         ELSE
            SetPos( ownd:nBottom, ownd:nLeft )
            ::aWindows[ ::nCurwindow ]:lFocused := .F.

            ::hashName:= ::hashName + "[" + HashKeyString( hHash, nSet ) + "]"
            ::AddWindows( HB_HValueAt( hHash, nSet ), oBrwSets:RowPos + oBrwSets:nTop )
            ::hashName := cOldName

            ADel( ::aWindows, ::nCurWindow )
            ASize( ::awindows, Len( ::awindows ) - 1 )
            IF ::nCurwindow == 0
               ::nCurwindow := 1
            ELSE
               ::nCurwindow--
            ENDIF
         ENDIF
      ELSEIF ISBLOCK( uValue ) .OR. ValType( uValue ) == "P"
         Alert( "Value cannot be edited" )
      ELSE
         IF ::lEditable
            oBrwSets:RefreshCurrent()
            IF ISOBJECT( uValue )
               __DbgObject( uValue, cName + "[" + HashKeyString( hHash, nSet ) + "]" )
            ELSEIF ISARRAY( uValue )
               __DbgArrays( uValue, cName + "[" + HashKeyString( hHash, nSet ) + "]" )
            ELSE
               ::doGet( oBrwSets, hHash, nSet )
            ENDIF
            oBrwSets:RefreshCurrent()
            oBrwSets:ForceStable()
         ELSE
            Alert( "Value cannot be edited" )
         ENDIF
      ENDIF

   ENDCASE

   RefreshVarsS( oBrwSets )

   ::aWindows[ ::nCurwindow ]:SetCaption( cName + "[" + LTrim( Str( oBrwSets:cargo[ 1 ] ) ) + ".." + ;
                                          LTrim( Str( Len( hHash ) ) ) + "]" )

   RETURN self
dbgthsh.prg220
FUNCTION__dbgHashes( hHash, cVarName, lEditable )
FUNCTION __dbgHashes( hHash, cVarName, lEditable )
   RETURN HBDbHash():New( hHash, cVarName, lEditable )
dbgthsh.prg297
STATIC FUNCTIONGetTopPos( nPos )
STATIC FUNCTION GetTopPos( nPos )
   RETURN iif( ( MaxRow() - nPos ) < 5, MaxRow() - nPos, nPos )
dbgthsh.prg300
STATIC FUNCTIONGetBottomPos( nPos )
STATIC FUNCTION GetBottomPos( nPos )
   RETURN iif( nPos < MaxRow() - 2, nPos, MaxRow()-2 )
dbgthsh.prg303
STATIC PROCEDURERefreshVarsS( oBrowse )
STATIC PROCEDURE RefreshVarsS( oBrowse )

   LOCAL nLen := oBrowse:colCount

   IF nLen == 2
      oBrowse:deHilite():colPos := 2
   ENDIF
   oBrowse:deHilite():forceStable()

   IF nLen == 2
      oBrowse:hilite():colPos := 1
   ENDIF
   oBrowse:hilite()

   RETURN
dbgthsh.prg306
STATIC FUNCTIONHashBrowseSkip( nPos, oBrwSets )
STATIC FUNCTION HashBrowseSkip( nPos, oBrwSets )
   RETURN iif( oBrwSets:cargo[ 1 ] + nPos < 1, 0 - oBrwSets:cargo[ 1 ] + 1 , ;
             iif( oBrwSets:cargo[ 1 ] + nPos > Len( oBrwSets:cargo[ 2 ][ 1 ] ), ;
                Len( oBrwSets:cargo[ 2 ][ 1 ] ) - oBrwSets:cargo[ 1 ], nPos ) )
dbgthsh.prg322
STATIC FUNCTIONHashKeyString( hHash, nAt )
STATIC FUNCTION HashKeyString( hHash, nAt )

   LOCAL xVal  := HB_HKeyAt( hHash, nAt )
   LOCAL cType := ValType( xVal )

   DO CASE
   CASE cType == "C" ; RETURN '"' + xVal + '"'
   CASE cType == "D" ; RETURN '"' + DToC( xVal ) + '"'
   CASE cType == "N" ; RETURN LTrim( Str( xVal ) )
   ENDCASE
  
   RETURN AllTrim( HB_CStr( xVal ) )
dbgthsh.prg327
dbgtmenu.prg
TypeFunctionSourceLine
METHODNew( aItems )
   METHOD New( aItems )
dbgtmenu.prg82
METHODAddItem( oMenuItem )
   METHOD AddItem( oMenuItem )
dbgtmenu.prg83
METHODBuild()
   METHOD Build()
dbgtmenu.prg84
METHODClosePopup()
   METHOD ClosePopup()
dbgtmenu.prg85
METHOD CLOSE() INLINE :ClosePopup( ::nOpenPopup ), ::nOpenPopup := 0
   METHOD Close() INLINE ::ClosePopup( ::nOpenPopup ), ::nOpenPopup := 0
dbgtmenu.prg86
METHODDeHilite()
   METHOD DeHilite()
dbgtmenu.prg87
METHODDisplay()
   METHOD Display()
dbgtmenu.prg88
METHODEvalAction()
   METHOD EvalAction()
dbgtmenu.prg89
METHODGetHotKeyPos( nKey )
   METHOD GetHotKeyPos( nKey )
dbgtmenu.prg90
METHODGetItemByIdent( uIdent )
   METHOD GetItemByIdent( uIdent )
dbgtmenu.prg91
METHODGetItemOrdByCoors( nRow, nCol )
   METHOD GetItemOrdByCoors( nRow, nCol )
dbgtmenu.prg92
METHODGoBottom()
   METHOD GoBottom()
dbgtmenu.prg93
METHOD GODOWN() INLINE ::AITEMS[ ::NOPENPOPUP ]:BACTIONGoRight()
   METHOD GoDown() INLINE ::aItems[ ::nOpenPopup ]:bAction:GoRight()
dbgtmenu.prg94
METHODGoLeft()
   METHOD GoLeft()
dbgtmenu.prg95
METHODGoRight()
   METHOD GoRight()
dbgtmenu.prg96
METHODGoTop()
   METHOD GoTop()
dbgtmenu.prg97
METHOD GOUP() INLINE ::AITEMS[ ::NOPENPOPUP ]:BACTIONGoLeft()
   METHOD GoUp() INLINE ::aItems[ ::nOpenPopup ]:bAction:GoLeft()
dbgtmenu.prg98
METHODIsOpen() INLINE ::nOpenPopup != 0
   METHOD IsOpen() INLINE ::nOpenPopup != 0
dbgtmenu.prg99
METHODLoadColors()
   METHOD LoadColors()                                 // Load current debugger colors settings
dbgtmenu.prg100
METHODProcessKey( nKey )
   METHOD ProcessKey( nKey )
dbgtmenu.prg101
METHODRefresh()
   METHOD Refresh()                                    // Repaints the top bar
dbgtmenu.prg102
METHODShowPopup( nPopup )
   METHOD ShowPopup( nPopup )

ENDCLASS
dbgtmenu.prg103
HBDBMENU:METHODNew() CLASS HBDbMenu
METHOD New() CLASS HBDbMenu

   local nCol := 0

   if ::aMenus == nil
      ::aMenus := {}
      ::lPopup := .f.
   else
      ::lPopup := .t.
   endif

   ::nTop         := 0
   ::nLeft        := 0
   ::nBottom      := 0
   ::nRight       := 0
   ::aItems       := {}
   ::LoadColors()
   ::nOpenPopup   := 0

   AAdd( ::aMenus, Self )

return Self
dbgtmenu.prg107
HBDBMENU:METHODAddItem( oMenuItem ) CLASS HBDbMenu
METHOD AddItem( oMenuItem ) CLASS HBDbMenu

   local oLastMenu := ATail( ::aMenus )
   local oLastMenuItem

   if oLastMenu:lPopup
      oMenuItem:nRow := Len( oLastMenu:aItems )
      oMenuItem:nCol := oLastMenu:nLeft + 1
   else
      oMenuItem:nRow := 0
      if Len( oLastMenu:aItems ) > 0
         oLastMenuItem := ATail( oLastMenu:aItems )
         oMenuItem:nCol := oLastMenuItem:nCol + ;
                          Len( StrTran( oLastMenuItem:cPrompt, "~", "" ) )
      else
         oMenuItem:nCol := 0
      endif
   endif

   AAdd( ATail( ::aMenus ):aItems, oMenuItem )

return oMenuItem
dbgtmenu.prg130
HBDBMENU:METHODBuild() CLASS HBDbMenu
METHOD Build() CLASS HBDbMenu

   local n
   local nPos := 0
   local oMenuItem

   if Len( ::aMenus ) == 1           // pulldown menu
      for n := 1 to Len( ::aItems )
         ::aItems[ n ]:nRow := 0
         ::aItems[ n ]:nCol := nPos
         nPos += Len( StrTran( ::aItems[ n ]:cPrompt, "~", "" ) )
      next
   else
      oMenuItem := ATail( ::aMenus[ Len( ::aMenus ) - 1 ]:aItems )
      ::nTop    := oMenuItem:nRow + 1
      ::nLeft   := oMenuItem:nCol
      nPos := ::nLeft
      for n := 1 to Len( ::aItems )
         ::aItems[ n ]:nRow := ::nTop + n
         ::aItems[ n ]:nCol := ::nLeft + 1
         nPos := Max( nPos, ::nLeft + Len( StrTran( ::aItems[ n ]:cPrompt, "~", "" ) ) + 1 )
      next
      ::nRight  := nPos + 1
      ::nBottom := ::nTop + Len( ::aItems ) + 1
      for n := 1 to Len( ::aItems )
         if ::aItems[ n ]:cPrompt != "-"
            ::aItems[ n ]:cPrompt := " " + PadR( ::aItems[ n ]:cPrompt, ::nRight - ::nLeft - 1 )
         endif
      next
      ATail( ::aMenus[ Len( ::aMenus ) - 1 ]:aItems ):bAction := ATail( ::aMenus )
      ::aMenus := ASize( ::aMenus, Len( ::aMenus ) - 1 )
   endif

return nil
dbgtmenu.prg153
HBDBMENU:METHODClosePopup( nPopup ) CLASS HBDbMenu
METHOD ClosePopup( nPopup ) CLASS HBDbMenu

   local oPopup

   if nPopup != 0
      oPopup := ::aItems[ nPopup ]:bAction
      if ValType( oPopup ) == "O"
         RestScreen( oPopup:nTop, oPopup:nLeft, oPopup:nBottom + 1, oPopup:nRight + 2,;
                     oPopup:cBackImage )
         oPopup:cBackImage := nil
      endif
      ::aItems[ nPopup ]:Display( ::cClrPopup, ::cClrHotKey )
   endif

return nil
dbgtmenu.prg188
HBDBMENU:METHODDeHilite() CLASS HBDbMenu
METHOD DeHilite() CLASS HBDbMenu

   local oMenuItem := ::aItems[ ::nOpenPopup ]

   oMenuItem:Display( ::cClrPopup, ::cClrHotKey )

return nil
dbgtmenu.prg204
HBDBMENU:METHODDisplay() CLASS HBDbMenu
METHOD Display() CLASS HBDbMenu

   local n

   SetColor( ::cClrPopup )

   if ! ::lPopup
      DispOutAt( 0, 0, Space( MaxCol() + 1 ), ::cClrPopup )
      SetPos( 0, 0 )
   else
      ::cBackImage := SaveScreen( ::nTop, ::nLeft, ::nBottom + 1, ::nRight + 2 )
      @ ::nTop, ::nLeft, ::nBottom, ::nRight BOX B_SINGLE
      hb_Shadow( ::nTop, ::nLeft, ::nBottom, ::nRight )
   endif

   for n := 1 to Len( ::aItems )
      if ::aItems[ n ]:cPrompt == "-"  // Separator
         DispOutAt( ::aItems[ n ]:nRow, ::nLeft,;
            Chr( 195 ) + Replicate( Chr( 196 ), ::nRight - ::nLeft - 1 ) + Chr( 180 ) )
      else
         ::aItems[ n ]:Display( ::cClrPopup, ::cClrHotKey )
      endif
   next

return nil
dbgtmenu.prg212
HBDBMENU:METHODEvalAction() CLASS HBDbMenu
METHOD EvalAction() CLASS HBDbMenu

   local oPopup, oMenuItem

   oPopup := ::aItems[ ::nOpenPopup ]:bAction
   oMenuItem := oPopup:aItems[ oPopup:nOpenPopup ]

   if oMenuItem:bAction != nil
      ::Close()
      Eval( oMenuItem:bAction, oMenuItem )
   endif

return nil
dbgtmenu.prg238
HBDBMENU:METHODGetHotKeyPos( cKey ) CLASS HBDbMenu
METHOD GetHotKeyPos( cKey ) CLASS HBDbMenu

   local n

   for n := 1 to Len( ::aItems )
      if Upper( SubStr( ::aItems[ n ]:cPrompt,;
         At( "~", ::aItems[ n ]:cPrompt ) + 1, 1 ) ) == cKey
         return n
      endif
   next

return 0
dbgtmenu.prg252
HBDBMENU:METHODGetItemOrdByCoors( nRow, nCol ) CLASS HBDbMenu
METHOD GetItemOrdByCoors( nRow, nCol ) CLASS HBDbMenu

   local n

   for n := 1 to Len( ::aItems )
      if ::aItems[ n ]:nRow == nRow .and. nCol >= ::aItems[ n ]:nCol .and. ;
         nCol <= ::aItems[ n ]:nCol + Len( ::aItems[ n ]:cPrompt ) - 2
         return n
      endif
   next

return 0
dbgtmenu.prg265
HBDBMENU:METHODGetItemByIdent( uIdent ) CLASS HBDbMenu
METHOD GetItemByIdent( uIdent ) CLASS HBDbMenu
  
   local n
   local oItem
  
   for n := 1 to Len( ::aItems )
      IF ISOBJECT( ::aItems[ n ]:bAction )
         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

return nil
dbgtmenu.prg278
HBDBMENU:METHODGoBottom() CLASS HBDbMenu
METHOD GoBottom() CLASS HBDbMenu

   local oPopup

   if ::IsOpen()
      oPopup := ::aItems[ ::nOpenPopup ]:bAction
      oPopup:DeHilite()
      oPopup:ShowPopup( Len( oPopup:aItems ) )
   endif

return nil
dbgtmenu.prg299
HBDBMENU:METHODGoLeft() CLASS HBDbMenu
METHOD GoLeft() CLASS HBDbMenu

   local oMenuItem := ::aItems[ ::nOpenPopup ]

   if ::nOpenPopup != 0
      if ! ::lPopup
         ::ClosePopup( ::nOpenPopup )
      else
         oMenuItem:Display( ::cClrPopup, ::CClrHotKey )
      endif
      if ::nOpenPopup > 1
         --::nOpenPopup
         do while ::nOpenPopup > 1 .and. ;
            SubStr( ::aItems[ ::nOpenPopup ]:cPrompt, 1, 1 ) == "-"
            --::nOpenPopup
         enddo
         ::ShowPopup( ::nOpenPopup )
      else
         ::ShowPopup( ::nOpenPopup := Len( ::aItems ) )
      endif
   endif

return nil
dbgtmenu.prg311
HBDBMENU:METHODGoRight() CLASS HBDbMenu
METHOD GoRight() CLASS HBDbMenu

   local oMenuItem := ::aItems[ ::nOpenPopup ]

   if ::nOpenPopup != 0
      if ! ::lPopup
         ::ClosePopup( ::nOpenPopup )
      else
         oMenuItem:Display( ::cClrPopup, ::cClrHotKey )
      endif
      if ::nOpenPopup < Len( ::aItems )
         ++::nOpenPopup
         do while ::nOpenPopup < Len( ::aItems ) .and. ;
            SubStr( ::aItems[ ::nOpenPopup ]:cPrompt, 1, 1 ) == "-"
            ++::nOpenPopup
         enddo
         ::ShowPopup( ::nOpenPopup )
      else
         ::ShowPopup( ::nOpenPopup := 1 )
      endif
   endif

return nil
dbgtmenu.prg335
HBDBMENU:METHODGoTop() CLASS HBDbMenu
METHOD GoTop() CLASS HBDbMenu

   local oPopup

   if ::IsOpen()
      oPopup := ::aItems[ ::nOpenPopup ]:bAction
      oPopup:DeHilite()
      oPopup:ShowPopup( 1 )
   endif

return nil
dbgtmenu.prg359
HBDBMENU:METHODLoadColors() CLASS HBDbMenu
METHOD LoadColors() CLASS HBDbMenu

   local aColors := __DbgColors()
   local n

   ::cClrPopup    := aColors[  8 ]
   ::cClrHotKey   := aColors[  9 ]
   ::cClrHilite   := aColors[ 10 ]
   ::cClrHotFocus := aColors[ 11 ]

   for n := 1 to Len( ::aItems )
      if ValType( ::aItems[ n ]:bAction ) == "O"
         ::aItems[ n ]:bAction:LoadColors()
      endif
   next

return nil
dbgtmenu.prg371
HBDBMENU:METHODRefresh() CLASS HBDbMenu
METHOD Refresh() CLASS HBDbMenu

   local n

   DispBegin()

   if ! ::lPopup
      DispOutAt( 0, 0, Space( MaxCol() + 1 ), ::cClrPopup )
      SetPos( 0, 0 )
   endif

   for n := 1 to Len( ::aItems )
      ::aItems[ n ]:Display( ::cClrPopup, ::cClrHotKey )
   next

   DispEnd()

return nil
dbgtmenu.prg389
HBDBMENU:METHODShowPopup( nPopup ) CLASS HBDbMenu
METHOD ShowPopup( nPopup ) CLASS HBDbMenu

   ::aItems[ nPopup ]:Display( ::cClrHilite, ::cClrHotFocus )
   ::nOpenPopup := nPopup

   if ValType( ::aItems[ nPopup ]:bAction ) == "O"
      ::aItems[ nPopup ]:bAction:Display()
      ::aItems[ nPopup ]:bAction:ShowPopup( 1 )
   endif

return nil
dbgtmenu.prg408
HBDBMENU:METHODProcessKey( nKey ) CLASS HBDbMenu
METHOD ProcessKey( nKey ) CLASS HBDbMenu

   local nPopup
   local oPopup

   do case
      case nKey == K_LBUTTONDOWN
           if MRow() == 0
              if ( nPopup := ::GetItemOrdByCoors( 0, MCol() ) ) != 0
                 if nPopup != ::nOpenPopup
                    ::ClosePopup( ::nOpenPopup )
                    ::ShowPopup( nPopup )
                 endif
              endif
           else
              oPopup := ::aItems[ ::nOpenPopup ]:bAction
              if ( nPopup := oPopup:GetItemOrdByCoors( MRow(), MCol() ) ) == 0
                 ::Close()
              else
                 oPopup:DeHilite()
                 oPopup:nOpenPopup := nPopup
                 oPopup:aItems[ nPopup ]:Display( ::cClrHilite, ::cClrHotFocus )
                 ::EvalAction()
              endif
           endif

      case nKey == K_ESC
           ::Close()

      case nKey == K_LEFT
           ::GoLeft()

      case nKey == K_RIGHT
           ::GoRight()

      case nKey == K_DOWN
           ::GoDown()

      case nKey == K_UP
           ::GoUp()

      case nKey == K_ENTER
           ::EvalAction()

      case nKey == K_HOME
           ::GoTop()

      case nKey == K_END
           ::GoBottom()

      otherwise

         if ::nOpenPopup > 0
            if IsAlpha( Chr( nKey ) )
               oPopup := ::aItems[ ::nOpenPopup ]:bAction
               nPopup := oPopup:GetHotKeyPos( Upper( Chr( nKey ) ) )
               if nPopup > 0 .and. oPopup:nOpenPopup != nPopup
                  oPopup:DeHilite()
                  oPopup:ShowPopup( nPopup )
                  ::EvalAction()
               endif
            endif
         else
            nPopup := ::GetHotKeyPos( __dbgAltToKey( nKey ) )
            if nPopup != ::nOpenPopup
               ::Close()
               ::ShowPopup( nPopup )
            endif
         endif

   endcase

return nil
dbgtmenu.prg420
FUNCTION__dbgAltToKey( nKey )
function __dbgAltToKey( nKey )

   local nIndex := AScan( { K_ALT_A, K_ALT_B, K_ALT_C, K_ALT_D, K_ALT_E, K_ALT_F,;
                            K_ALT_G, K_ALT_H, K_ALT_I, K_ALT_J, K_ALT_K, K_ALT_L,;
                            K_ALT_M, K_ALT_N, K_ALT_O, K_ALT_P, K_ALT_Q, K_ALT_R,;
                            K_ALT_S, K_ALT_T, K_ALT_U, K_ALT_V, K_ALT_W, K_ALT_X,;
                            K_ALT_Y, K_ALT_Z, K_ALT_1, K_ALT_2, K_ALT_3, K_ALT_4,;
                            K_ALT_5, K_ALT_6, K_ALT_7, K_ALT_8, K_ALT_9, K_ALT_0 }, nKey )

return iif( nIndex > 0, SubStr( "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", nIndex, 1 ), "" )
dbgtmenu.prg495
dbgtmitm.prg
TypeFunctionSourceLine
METHODNew( cPrompt, bAction, lChecked, xIdent )
   METHOD New( cPrompt, bAction, lChecked, xIdent )
dbgtmitm.prg73
METHODDisplay( cClrText, cClrHotKey )
   METHOD Display( cClrText, cClrHotKey )
dbgtmitm.prg74
METHODToggle() INLINE ::lChecked := ! ::lChecked
   METHOD Toggle() INLINE ::lChecked := ! ::lChecked

ENDCLASS
dbgtmitm.prg75
HBDBMENUITEM:METHODNew( cPrompt, bAction, lChecked, xIdent ) CLASS HBDbMenuItem
METHOD New( cPrompt, bAction, lChecked, xIdent ) CLASS HBDbMenuItem

   DEFAULT lChecked TO .F.

   ::cPrompt  := cPrompt
   ::bAction  := bAction
   ::lChecked := lChecked
   ::Ident    := xIdent

   RETURN Self
dbgtmitm.prg79
HBDBMENUITEM:METHODDisplay( cClrText, cClrHotKey ) CLASS HBDbMenuItem
METHOD Display( cClrText, cClrHotKey ) CLASS HBDbMenuItem

   LOCAL nAt

   DispOutAt( ::nRow, ::nCol, StrTran( ::cPrompt, "~", "" ), cClrText )

   DispOutAt( ::nRow, ::nCol + ;
     ( nAt := At( "~", ::cPrompt ) ) - 1,;
     SubStr( ::cPrompt, nAt + 1, 1 ), cClrHotKey )

   DispOutAt( ::nRow, ::nCol, iif( ::lChecked, Chr( 251 ), "" ), cClrText )

   RETURN Self
dbgtmitm.prg90
dbgtobj.prg
TypeFunctionSourceLine
METHODNew( oObject, cVarName, lEditable )
   METHOD New( oObject, cVarName, lEditable )
dbgtobj.prg71
METHODaddWindows( aArray, nRow )
   METHOD addWindows( aArray, nRow )
dbgtobj.prg72
METHODdoGet( oBrowse, pItem, nSet )
   METHOD doGet( oBrowse, pItem, nSet )
dbgtobj.prg73
METHODSetsKeyPressed( nKey, oBrwSets, nSets, aArray )
   METHOD SetsKeyPressed( nKey, oBrwSets, nSets, aArray )

ENDCLASS
dbgtobj.prg74
HBDBOBJECT:METHODNew( oObject, cVarName, lEditable ) CLASS HBDbObject
METHOD New( oObject, cVarName, lEditable ) CLASS HBDbObject

   LOCAL cMsg, cMsgAcc
   LOCAL aMessages, aMethods
   LOCAL xValue

   DEFAULT lEditable TO .T.

   /* create list of object messages */
   aMessages := oObject:classSel()
   ASort( aMessages,,, {|x,y| PAdR( x, 64 ) <= PAdR( y, 64 ) } )
   aMethods := {}
   FOR EACH cMsg IN aMessages
      IF Left( cMsg, 1 ) == "_" .AND. ;
         HB_AScan( aMessages, cMsgAcc := Substr( cMsg, 2 ),,, .T. ) != 0
         xValue := __dbgObjGetValue( oObject, cMsgAcc )
         AAdd( ::pItems, { cMsgAcc, xValue, .T. } )
         AAdd( ::AllNames, cMsgAcc )
      ELSEIF HB_AScan( aMessages, "_" + cMsg,,, .T. ) == 0
         AAdd( aMethods, cMsg )
      ENDIF
   NEXT
   FOR EACH cMsg IN aMethods
      AAdd( ::pItems, { Lower( cMsg ), "Method", .F. } )
      AAdd( ::AllNames, cMsg )
   NEXT

   ::objname := cVarName
   ::TheObj := oObject
   ::lEditable := lEditable

   ::addWindows( ::pItems )

   RETURN Self
dbgtobj.prg78
HBDBOBJECT:METHODaddWindows( aArray, nRow ) CLASS HBDbObject
METHOD addWindows( aArray, nRow ) CLASS HBDbObject

   LOCAL oBrwSets
   LOCAL nSize := Len( aArray )
   LOCAL oWndSets
   LOCAL nWidth
   LOCAL oCol
   LOCAL nMaxLen

   IF nSize < MaxRow()-2
      IF nRow != NIL
         oWndSets := HBDbWindow():New( nRow, 5, iif( nRow + nSize + 1 < MaxRow() - 2, nRow + nSize + 1, MaxRow() - 2 ), MaxCol() - 5, ::objname + " is of class: " + ::TheObj:ClassName(), "N/W" )
      ELSE
         oWndSets := HBDbWindow():New( 1, 5, 2 + nSize, MaxCol() - 5, ::objname + " is of class: " + ::TheObj:ClassName(), "N/W" )
      ENDIF
   ELSE
      oWndSets := HBDbWindow():New( 1, 5, MaxRow() - 2, MaxCol() - 5, ::objname + " is of class: " + ::TheObj:ClassName(), "N/W" )
   ENDIF

   ::nCurWindow++
   oWndSets:lFocused := .T.
   AAdd( ::aWindows, oWndSets )

   nWidth := oWndSets:nRight - oWndSets:nLeft - 1

   oBrwSets := HBDbBrowser():New( oWndSets:nTop + 1, oWndSets:nLeft + 1, oWndSets:nBottom - 1, oWndSets:nRight - 1 )
   ::ArrayReference := aArray

   oBrwSets:autolite := .T.
   oBrwSets:ColorSpec := __Dbg():ClrModal()
   oBrwSets:GoTopBlock := { || ::Arrayindex := 1 }
   oBrwSets:GoBottomBlock := { || ::arrayindex := Len( ::ArrayReference ) }
   oBrwSets:SkipBlock := { | nSkip, nPos | nPos := ::arrayindex,;
                          ::arrayindex := iif( nSkip > 0, Min( ::arrayindex + nSkip, Len( ::arrayReference ) ),;
                          Max( 1, ::arrayindex + nSkip ) ), ::arrayindex - nPos }

   nMaxLen := ArrayMaxLen( ::AllNames )
   oBrwSets:AddColumn( oCol := TBColumnNew( "",;
                    { || PadR( ::ArrayReference[ ::arrayindex, 1 ], nMaxLen ) } ) )
   oCol:width := nMaxLen
   oCol:ColorBlock := { || { iif( ::Arrayindex == oBrwSets:Cargo, 2, 1 ), 2 } }
   oBrwSets:Freeze := 1

   oBrwSets:AddColumn( oCol := TBColumnNew( "", { || iif( ISCHARACTER( ::ArrayReference[ ::ArrayIndex, 2 ] ) .AND. !::ArrayReference[ ::ArrayIndex, 3 ],;
      ::ArrayReference[ ::ArrayIndex, 2 ],;
      PadR( __dbgValToStr( __dbgObjGetValue( ::TheObj, ::ArrayReference[ ::arrayindex, 1 ] ) ), nWidth  - 12 ) ) } ) )

   oBrwSets:Cargo := 1 // Actual highlighted row
   oCol:ColorBlock := { || { iif( ::Arrayindex == oBrwSets:Cargo, 3, 1 ), 3 } }
   oCol:width := MaxCol() - 14 - nMaxLen
   oBrwSets:colPos := 2
   ::aWindows[ ::nCurWindow ]:bPainted    := { || oBrwSets:ForceStable() }
   ::aWindows[ ::nCurWindow ]:bKeyPressed := { | nKey | ::SetsKeyPressed( nKey, oBrwSets, Len( aArray ), ::ArrayReference ) }
   ::aWindows[ ::nCurwindow ]:cCaption := ::objname + " is of class: " +::TheObj:ClassName()

   SetCursor( SC_NONE )

   ::aWindows[ ::nCurWindow ]:ShowModal()

   RETURN Self
dbgtobj.prg113
HBDBOBJECT:METHODdoGet( oBrowse, pItem, nSet ) CLASS HBDbObject
METHOD doGet( oBrowse, pItem, nSet ) CLASS HBDbObject

#ifndef HB_NO_READDBG

   LOCAL column
   LOCAL nKey
   LOCAL GetList := {}
   LOCAL lScoreSave := Set( _SET_SCOREBOARD, .F. )
   LOCAL lExitSave  := Set( _SET_EXIT, .T. )
   LOCAL bInsSave   := SetKey( K_INS )
   LOCAL cValue
   LOCAL lCanAcc
   LOCAL oErr

   // make sure browse is stable
   oBrowse:forceStable()
   // if confirming new record, append blank


   // get column object from browse
   column := oBrowse:getColumn( oBrowse:colPos )

   // create a corresponding GET
   cValue := __dbgObjGetValue( ::TheObj, pitem[ nSet, 1 ], @lCanAcc )
   IF !lCanAcc
      Alert( cValue )
      RETURN NIL
   ENDIF
   cValue := PadR( __dbgValToStr( cValue ), column:Width )

   // set insert key to toggle insert mode and cursor
   SetKey( K_INS, { || SetCursor( iif( ReadInsert( ! ReadInsert() ),;
                                       SC_NORMAL, SC_INSERT ) ), inkey(0) } )

   // initial cursor setting
   SetCursor( iif( ReadInsert(), SC_INSERT, SC_NORMAL ) )

   @ Row(), oBrowse:nLeft + oBrowse:GetColumn( 1 ):width + 1 GET cValue ;
       VALID iif( Type( cValue ) == "UE", ( Alert( "Expression error" ), .F. ), .T. )

   READ

   SetCursor( SC_NONE )
   Set( _SET_SCOREBOARD, lScoreSave )
   Set( _SET_EXIT, lExitSave )
   SetKey( K_INS, bInsSave )

   IF LastKey() == K_ENTER
      BEGIN SEQUENCE WITH {|oErr| break( oErr ) }
         __dbgObjSetValue( ::TheObj, pitem[ nSet, 1 ], &cValue )
      RECOVER USING oErr
         Alert( oErr:description )
      END SEQUENCE
   ENDIF

   // check exit key from get
   nKey := LastKey()
   IF nKey == K_UP .OR. nKey == K_DOWN .OR. nKey == K_PGUP .OR. nKey == K_PGDN
      KEYBOARD Chr( nKey )
   ENDIF

#else

   HB_SYMBOL_UNUSED( oBrowse )
   HB_SYMBOL_UNUSED( pItem )
   HB_SYMBOL_UNUSED( nSet )

#endif

   RETURN NIL
dbgtobj.prg174
HBDBOBJECT:METHODSetsKeyPressed( nKey, oBrwSets, nSets, aArray ) CLASS HBDbObject
METHOD SetsKeyPressed( nKey, oBrwSets, nSets, aArray ) CLASS HBDbObject

   LOCAL nSet := oBrwSets:Cargo
   LOCAL cOldname := ::objname

   DO CASE
   CASE nKey == K_UP

      IF oBrwSets:Cargo > 1
         oBrwSets:Cargo--
         oBrwSets:RefreshCurrent()
         oBrwSets:Up()
         oBrwSets:ForceStable()
      ENDIF

   CASE nKey == K_DOWN

      IF oBrwSets:Cargo < nSets
         oBrwSets:Cargo++
         oBrwSets:RefreshCurrent()
         oBrwSets:Down()
         oBrwSets:ForceStable()
      ENDIF

   CASE nKey == K_HOME .OR. nKey == K_CTRL_PGUP .OR. nKey == K_CTRL_HOME

      IF oBrwSets:Cargo > 1
         oBrwSets:Cargo := 1
         oBrwSets:GoTop()
         oBrwSets:ForceStable()
      ENDIF

   CASE nKey == K_END .OR. nKey == K_CTRL_PGDN .OR. nKey == K_CTRL_END

      IF oBrwSets:Cargo < nSets
         oBrwSets:Cargo := nSets
         oBrwSets:GoBottom()
         oBrwSets:ForceStable()
      ENDIF

   CASE nKey == K_PGUP

      oBrwSets:PageUp()
      oBrwSets:Cargo := ::ArrayIndex
      oBrwSets:RefreshCurrent()
      oBrwSets:ForceStable()

   CASE nKey == K_PGDN

      oBrwSets:PageDown()
      oBrwSets:Cargo := ::ArrayIndex
      oBrwSets:RefreshCurrent()
      oBrwSets:ForceStable()

   CASE nKey == K_ENTER

      IF nSet == oBrwSets:Cargo
         IF ISARRAY( aArray[ nSet, 2 ] )
            IF Len( aArray[ nSet, 2 ] ) > 0
               HBDbArray():New( aArray[ nSet, 2 ], ::pitems[ nSet, 1 ] )
            ENDIF
         ELSEIF ValType( aArray[ nSet, 2 ] ) == "H"
            IF Len( aArray[ nSet, 2 ] ) > 0
               HBDbHash():New( aArray[ nSet, 2 ], ::pitems[ nSet, 1 ] )
            ENDIF
         ELSEIF ISOBJECT( aArray[ nSet, 2 ] )
            HBDbObject():New( aArray[ nSet, 2 ], ::pitems[ nSet, 1 ] )
         ELSEIF ( ISCHARACTER( aArray[ nSet, 2 ] ) .AND. ;
                  !aArray[ nSet, 3 ] ) .OR. ;
                ISBLOCK( aArray[ nSet, 2 ] ) .OR. ;
                ValType( aArray[ nSet, 2 ] ) == "P"
            Alert( "Value cannot be edited" )
         ELSE
            IF ::lEditable
               oBrwSets:RefreshCurrent()
               ::doGet( oBrwSets, ::arrayReference, nSet )
               oBrwSets:RefreshCurrent()
               oBrwSets:ForceStable()
            else
               Alert( "Value cannot be edited" )
            ENDIF
         ENDIF
      ENDIF

   ENDCASE

   RETURN NIL
dbgtobj.prg245
FUNCTION__dbgObject( aArray, cVarName, lEditable )
FUNCTION __dbgObject( aArray, cVarName, lEditable )
   RETURN HBDbObject():New( aArray, cVarName, lEditable )
dbgtobj.prg333
STATIC FUNCTIONArrayMaxLen( aArray )
STATIC FUNCTION ArrayMaxLen( aArray )

   LOCAL nMaxLen := 0
   LOCAL nLen
   LOCAL cItem

   FOR EACH cItem IN aArray
      nLen := Len( cItem )
      IF nMaxLen < nLen
         nMaxLen := nLen
      ENDIF
   NEXT

   RETURN nMaxLen
dbgtobj.prg336
STATIC FUNCTION__dbgObjGetValue( oObject, cVar, lCanAcc )
STATIC FUNCTION __dbgObjGetValue( oObject, cVar, lCanAcc )

   LOCAL nProcLevel := __Dbg():nProcLevel
   LOCAL xResult
   LOCAL oErr

   BEGIN SEQUENCE WITH {|| break() }
      xResult := __dbgSENDMSG( nProcLevel, oObject, cVar )
      lCanAcc := .T.
   RECOVER
      BEGIN SEQUENCE WITH {|oErr| break( oErr ) }
         /* Try to access variables using class code level */
         xResult := __dbgSENDMSG( 0, oObject, cVar )
         lCanAcc := .T.
      RECOVER USING oErr
         xResult := oErr:description
         lCanAcc := .F.
      END SEQUENCE
   END SEQUENCE

   RETURN xResult
dbgtobj.prg351
STATIC FUNCTION__dbgObjSetValue( oObject, cVar, xValue )
STATIC FUNCTION __dbgObjSetValue( oObject, cVar, xValue )

   LOCAL nProcLevel := __Dbg():nProcLevel
   LOCAL oErr

   BEGIN SEQUENCE WITH {|| break() }
      __dbgSENDMSG( nProcLevel, oObject, "_" + cVar, xValue )
   RECOVER
      BEGIN SEQUENCE WITH {|oErr| break( oErr ) }
         /* Try to access variables using class code level */
         __dbgSENDMSG( 0, oObject, "_" + cVar, xValue )
      RECOVER USING oErr
         Alert( oErr:description )
      END SEQUENCE
   END SEQUENCE

   RETURN xValue
dbgtobj.prg373
dbgtwin.prg
TypeFunctionSourceLine
METHODNew( nTop, nLeft, nBottom, nRight, cCaption, cColor )
   METHOD New( nTop, nLeft, nBottom, nRight, cCaption, cColor )
dbgtwin.prg97
METHODHide()
   METHOD Hide()
dbgtwin.prg99
METHODIsOver( nRow, nCol )
   METHOD IsOver( nRow, nCol )
dbgtwin.prg100
METHODnWidth() INLINE ::nRight - ::nLeft + 1
   METHOD nWidth() INLINE ::nRight - ::nLeft + 1
dbgtwin.prg101
METHODClear()
   METHOD Clear()
dbgtwin.prg102
METHODScrollUp( nLines )
   METHOD ScrollUp( nLines )
dbgtwin.prg103
METHODSetCaption( cCaption )
   METHOD SetCaption( cCaption )
dbgtwin.prg104
METHODShowCaption()
   METHOD ShowCaption()
dbgtwin.prg105
METHODSetFocus( lOnOff )
   METHOD SetFocus( lOnOff )
dbgtwin.prg106
METHODShow( lFocused )
   METHOD Show( lFocused )
dbgtwin.prg107
METHODShowModal()
   METHOD ShowModal()
dbgtwin.prg108
METHODLButtonDown( nMRow, nMCol )
   METHOD LButtonDown( nMRow, nMCol )
dbgtwin.prg109
METHODLDblClick( nMRow, nMCol )
   METHOD LDblClick( nMRow, nMCol )
dbgtwin.prg110
METHODLoadColors()
   METHOD LoadColors()
dbgtwin.prg111
METHODMove()
   METHOD Move()
dbgtwin.prg113
METHODKeyPressed( nKey )
   METHOD KeyPressed( nKey )
dbgtwin.prg114
METHODRefresh()
   METHOD Refresh()
dbgtwin.prg115
METHODResize()
   METHOD Resize()

ENDCLASS
dbgtwin.prg116
HBDBWINDOW:METHODNew( nTop, nLeft, nBottom, nRight, cCaption, cColor ) CLASS HBDbWindow
METHOD New( nTop, nLeft, nBottom, nRight, cCaption, cColor ) CLASS HBDbWindow

   DEFAULT cColor TO __DbgColors()[ 1 ]

   ::nTop     := nTop
   ::nLeft    := nLeft
   ::nBottom  := nBottom
   ::nRight   := nRight
   ::cCaption := cCaption
   ::cColor   := cColor

return Self
dbgtwin.prg120
HBDBWINDOW:METHODClear() CLASS HBDbWindow
METHOD Clear() CLASS HBDbWindow
  
   SetColor( ::cColor )
   Scroll( ::nTop + 1, ::nLeft + 1, ::nBottom - 1, ::nRight - 1 )

return nil
dbgtwin.prg133
HBDBWINDOW:METHODHide() CLASS HBDbWindow
METHOD Hide() CLASS HBDbWindow

   RestScreen( ::nTop, ::nLeft, ::nBottom + iif( ::lShadow, 1, 0 ),;
               ::nRight + iif( ::lShadow, 2, 0 ), ::cBackImage )
   ::cBackImage := nil
   ::lVisible := .f.

return nil
dbgtwin.prg140
HBDBWINDOW:METHODIsOver( nRow, nCol ) CLASS HBDbWindow
METHOD IsOver( nRow, nCol ) CLASS HBDbWindow

return nRow >= ::nTop .and. nRow <= ::nBottom .and. ;
       nCol >= ::nLeft .and. nCol <= ::nRight
dbgtwin.prg149
HBDBWINDOW:METHODScrollUp( nLines ) CLASS HBDbWindow
METHOD ScrollUp( nLines ) CLASS HBDbWindow

   DEFAULT nLines TO 1

   SetColor( ::cColor )
   Scroll( ::nTop + 1, ::nLeft + 1, ::nBottom - 1, ::nRight - 1, nLines )

return nil
dbgtwin.prg154
HBDBWINDOW:METHODSetCaption( cCaption ) CLASS HBDbWindow
METHOD SetCaption( cCaption ) CLASS HBDbWindow

   ::cCaption := cCaption

return nil
dbgtwin.prg163
HBDBWINDOW:METHODShowCaption CLASS HBDbWindow
METHOD ShowCaption CLASS HBDbWindow

   if ! Empty( ::cCaption )
      DispOutAt( ::nTop, ::nLeft + ( ( ::nRight - ::nLeft ) / 2 ) - ;
         ( ( Len( ::cCaption ) + 2 ) / 2 ),;
         " " + ::cCaption + " ", ::cColor )
   endif

return nil
dbgtwin.prg169
HBDBWINDOW:METHODSetFocus( lOnOff ) CLASS HBDbWindow
METHOD SetFocus( lOnOff ) CLASS HBDbWindow
  
   if ! lOnOff .and. ::bLostFocus != nil
      Eval( ::bLostFocus, Self )
   endif

   ::lFocused := lOnOff

   if lOnOff .and. ::bGotFocus != nil
      Eval( ::bGotFocus, Self )
   endif

return nil
dbgtwin.prg179
HBDBWINDOW:METHODRefresh() CLASS HBDbWindow
METHOD Refresh() CLASS HBDbWindow

   DispBegin()

   @ ::nTop, ::nLeft, ::nBottom, ::nRight BOX iif( ::lFocused, B_DOUBLE, B_SINGLE ) ;
      COLOR ::cColor

   DispOutAt( ::nTop, ::nLeft + 1, "[" + Chr( 254 ) + "]", ::cColor )

   ::ShowCaption( ::cCaption )

   if ::bPainted != nil
      Eval( ::bPainted, Self )
   endif
   
   DispEnd()

return nil
dbgtwin.prg193
HBDBWINDOW:METHODShow( lFocused ) CLASS HBDbWindow
METHOD Show( lFocused ) CLASS HBDbWindow
   LOCAL nRow := Row()
   LOCAL nCol := Col()

   DEFAULT lFocused TO ::lFocused
   
   ::cBackImage := SaveScreen( ::nTop, ::nLeft, ::nBottom + iif( ::lShadow, 1, 0 ),;
                              ::nRight + iif( ::lShadow, 2, 0 ) )
   SetColor( ::cColor )
   Scroll( ::nTop, ::nLeft, ::nBottom, ::nRight )
   ::SetFocus( lFocused )

   if ::lShadow
      hb_Shadow( ::nTop, ::nLeft, ::nBottom, ::nRight )
   endif

   ::Refresh()
   ::lVisible := .t.

   SetPos( nRow, nCol )

return nil
dbgtwin.prg212
HBDBWINDOW:METHODShowModal() CLASS HBDbWindow
METHOD ShowModal() CLASS HBDbWindow

   local lExit := .f.
   local nKey

   ::lShadow := .t.
   ::Show()

   do while ! lExit
      nKey := Inkey( 0, INKEY_ALL )

      if ::bKeyPressed != nil
         Eval( ::bKeyPressed, nKey )
      endif

      do case
      case nKey == K_ESC
         lExit := .t.

      case nKey == K_LBUTTONDOWN
         if MRow() == ::nTop .and. MCol() >= ::nLeft + 1 .and. ;
            MCol() <= ::nLeft + 3
            lExit := .t.
         endif
      endcase
   enddo

   ::Hide()

return nil
dbgtwin.prg235
HBDBWINDOW:METHODLButtonDown( nMRow, nMCol ) CLASS HBDbWindow
METHOD LButtonDown( nMRow, nMCol ) CLASS HBDbWindow

   if ::bLButtonDown != nil
      Eval( ::bLButtonDown, nMRow, nMCol )
   endif

return nil
dbgtwin.prg266
HBDBWINDOW:METHODLDblClick( nMRow, nMCol ) CLASS HBDbWindow
METHOD LDblClick( nMRow, nMCol ) CLASS HBDbWindow

   if ::bLDblClick != nil
      Eval( ::bLDblClick, nMRow, nMCol )
   endif

return nil
dbgtwin.prg274
HBDBWINDOW:METHODMove() Class HBDbWindow
METHOD Move() Class HBDbWindow

   local nOldTop    := ::nTop
   local nOldLeft   := ::nLeft
   local nOldBottom := ::nbottom
   local nOldRight  := ::nright
   local nKey

   do while .t.
      RestScreen( ,,,, ::cbackimage )
      DispBox( ::nTop, ::nLeft, ::nRight, ::nBottom, Replicate( Chr( 176 ), 8 ) + " " )

      nKey := Inkey( 0 )

      do case
      case nKey == K_UP

         if ::ntop != 0
            ::ntop--
            ::nbottom--
         endif

      case nKey == K_DOWN

         if ::nBottom != MaxRow()
            ::nTop++
            ::nBottom++
         endif

      case nKey == K_LEFT

         if ::nLeft != 0
            ::nLeft--
            ::nRight--
         endif

      case nKey == K_RIGHT

         if ::nBottom != MaxRow()
            ::nLeft++
            ::nRight++
         endif

      case nKey == K_ESC

         ::nTop    := nOldTop
         ::nLeft   := nOldLeft
         ::nBottom := nOldBottom
         ::nRight  := nOldRight

      endcase

      if nKey == K_ESC .or. nKey == K_ENTER
         exit
      endif
   enddo

   // __Keyboard( Chr( 0 ) ), Inkey() )

return nil
dbgtwin.prg282
HBDBWINDOW:METHODKeyPressed( nKey ) CLASS HBDbWindow
METHOD KeyPressed( nKey ) CLASS HBDbWindow

   if ::bKeyPressed != NIL
      Eval( ::bKeyPressed, nKey, Self )
   endif

return nil
dbgtwin.prg343
HBDBWINDOW:METHODLoadColors() CLASS HBDbWindow
METHOD LoadColors() CLASS HBDbWindow

   local aClr := __DbgColors()
  
   ::cColor := aClr[ 1 ]

   IF ::Browser != NIL
      ::Browser:ColorSpec := aClr[ 2 ] + "," + aClr[ 5 ] + "," + aClr[ 3 ]
   ENDIF

return nil
dbgtwin.prg351
HBDBWINDOW:METHODResize( nTop, nLeft, nBottom, nRight ) CLASS HBDbWindow
METHOD Resize( nTop, nLeft, nBottom, nRight ) CLASS HBDbWindow

   local lShow
  
   if ( nTop == NIL .OR. nTop == ::nTop ) .AND. ;
      ( nLeft == NIL .OR. nLeft == ::nLeft ) .AND. ;
      ( nBottom == NIL .OR. nBottom == ::nBottom ) .AND. ;
      ( nRight == NIL .OR. nRight == ::nRight )
      return Self
   endif
  
   if ( lShow := ::lVisible )
      ::Hide()
   endif

   if nTop != NIL
      ::nTop := nTop
   endif
   if nBottom != NIL
      ::nBottom := nBottom
   endif
   if nLeft != NIL
      ::nLeft := nLeft
   endif
   if nRight != NIL
      ::nRight := nRight
   endif
  
   if ::Browser != NIL
      ::Browser:Resize( ::nTop + 1, ::nLeft + 1, ::nBottom - 1, ::nRight - 1 )
   endif
  
   if lShow
      ::Show( ::lFocused )
   endif

return self
dbgtwin.prg363
dbgwa.prg
TypeFunctionSourceLine
PROCEDURE__dbgShowWorkAreas()
procedure __dbgShowWorkAreas()

   local oDlg
   local oCol

   local aAlias := {}
   local aBrw[ 3 ]
   local aStruc
   local aInfo

   local cColor := iif( __Dbg():lMonoDisplay, "N/W, W/N, W+/W, W+/N", "N/W, N/BG, R/W, R/BG" )

   local n1
   local n2
   local n3 := 1
   local cur_id := 1

   local nOldArea := Select()

   /* We can't determine the last used area, so use 512 here */
   for n1 := 1 to 512
      if ( n1 )->( Used() )
         AAdd( aAlias, { n1, Alias( n1 ) } )
         if n1 == nOldArea
            cur_id := Len( aAlias )
         endif
      endif
   next

   if Len( aAlias ) == 0
      Alert( "No workareas in use")
      return
   endif

   IF !Used()
      dbSelectArea( aAlias[ 1 ][ 1 ] )
   ENDIF

   /* Window creation */

   oDlg := HBDbWindow():New( 2, 3, 21, 74, "", cColor )

   oDlg:bKeyPressed := { | nKey | DlgWorkAreaKey( nKey, oDlg, aBrw, aAlias, @aStruc, @aInfo ) }
   oDlg:bPainted    := { || DlgWorkAreaPaint( oDlg, aBrw ) }

   /* Alias browse */

   aBrw[ 1 ] := HBDbBrowser():new( oDlg:nTop + 1, oDlg:nLeft + 1, oDlg:nBottom - 1, oDlg:nLeft + 11 )

   aBrw[ 1 ]:Cargo         := ( n1 := cur_id )
   aBrw[ 1 ]:ColorSpec     := oDlg:cColor
   aBrw[ 1 ]:GoTopBlock    := { || aBrw[ 1 ]:Cargo := n1 := 1 }
   aBrw[ 1 ]:GoBottomBlock := { || aBrw[ 1 ]:Cargo := n1 := Len( aAlias ) }
   aBrw[ 1 ]:SkipBlock     := { | nSkip, nPos | nPos := n1,;
                                  aBrw[ 1 ]:Cargo := n1 := iif( nSkip > 0, Min( Len( aAlias ), n1 + nSkip ),;
                                          Max( 1, n1 + nSkip ) ),;
                                  n1 - nPos }

   aBrw[ 1 ]:AddColumn( oCol := TBColumnNew( "", { || PadR( aAlias[ n1 ][ 2 ], 11 ) } ) )

   oCol:ColorBlock := { || iif( aAlias[ n1 ][ 1 ] == Select(), { 3, 4 }, { 1, 2 } ) }

   /* Info Browse */

   aInfo := ( aAlias[ n1 ][ 1 ] )->( DbfInfo() )

   aBrw[ 2 ] := HBDbBrowser():new( oDlg:nTop + 7, oDlg:nLeft + 13, oDlg:nBottom - 1, oDlg:nLeft + 50 )

   aBrw[ 2 ]:Cargo         := ( n2 := 1 )
   aBrw[ 2 ]:ColorSpec     := oDlg:cColor
   aBrw[ 2 ]:GoTopBlock    := { || aBrw[ 2 ]:Cargo := n2 := 1 }
   aBrw[ 2 ]:GoBottomBlock := { || aBrw[ 2 ]:Cargo := n2 := Len( aInfo ) }
   aBrw[ 2 ]:SkipBlock     := { | nSkip, nPos | nPos := n2, ;
                                aBrw[ 2 ]:Cargo := n2 := iif( nSkip > 0, Min( Len( aInfo ), n2 + nSkip ), ;
                                                                         Max( 1, n2 + nSkip ) ), ;
                                n2 - nPos }

   aBrw[ 2 ]:AddColumn( oCol := TBColumnNew( "", { || PadR( aInfo[ n2 ], 38 ) } ) )

   oCol:ColorBlock := { || iif( aAlias[ n1 ][ 1 ] == Select() .and. n2 == 1, { 3, 4 }, { 1, 2 } ) }

   /* Struc browse */

   aStruc := ( aAlias[ n1 ][ 1 ] )->( DbStruct() )

   aBrw[ 3 ] := HBDbBrowser():new( oDlg:nTop + 1, oDlg:nLeft + 52, oDlg:nBottom - 1, oDlg:nLeft + 70 )

   aBrw[ 3 ]:Cargo         := n3 := 1
   aBrw[ 3 ]:ColorSpec     := oDlg:cColor
   aBrw[ 3 ]:GoTopBlock    := { || aBrw[ 3 ]:Cargo := n3 := 1 }
   aBrw[ 3 ]:GoBottomBlock := { || aBrw[ 3 ]:Cargo := n3 := Len( aStruc ) }
   aBrw[ 3 ]:SkipBlock     := { | nSkip, nPos | nPos := n3,;
                                  aBrw[ 3 ]:Cargo := n3 := iif( nSkip > 0, Min( Len( aStruc ), n3 + nSkip ),;
                                          Max( 1, n3 + nSkip ) ), n3 - nPos }

   aBrw[ 3 ]:AddColumn( TBColumnNew( "", { || PadR( aStruc[ n3, 1 ], 11 ) + ;
                                              aStruc[ n3, 2 ] + ;
                                              Str( aStruc[ n3, 3 ], 4 ) + ;
                                              Str( aStruc[ n3, 4 ], 3 ) } ) )

   /* Show dialog */

   oDlg:ShowModal()
   
   dbSelectArea( nOldArea )

return
dbgwa.prg57
STATIC PROCEDUREDlgWorkAreaPaint( oDlg, aBrw )
static procedure DlgWorkAreaPaint( oDlg, aBrw )

   /* Display captions */

   DispOutAt( oDlg:nTop, oDlg:nLeft + 5, " Area ", oDlg:cColor )
   DispOutAt( oDlg:nTop, oDlg:nLeft + 28, " Status ", oDlg:cColor )
   DispOutAt( oDlg:nTop, oDlg:nLeft + 56, " Structure ", oDlg:cColor )

   /* Display separator lines */

   @ oDlg:nTop + 1, oDlg:nLeft + 12 TO ;
     oDlg:nBottom - 1, oDlg:nLeft + 12 ;
     COLOR oDlg:cColor

   DispOutAt( oDlg:nTop, oDlg:nLeft + 12, Chr( 194 ), oDlg:cColor )
   DispOutAt( oDlg:nBottom, oDlg:nLeft + 12, Chr( 193 ), oDlg:cColor )

   @ oDlg:nTop + 1, oDlg:nLeft + 51 TO ;
     oDlg:nBottom - 1, oDlg:nLeft + 51 ;
     COLOR oDlg:cColor

   DispOutAt( oDlg:nTop, oDlg:nLeft + 51, Chr( 194 ), oDlg:cColor )
   DispOutAt( oDlg:nBottom, oDlg:nLeft + 51, Chr( 193 ), oDlg:cColor )

   @ oDlg:nTop + 6, oDlg:nLeft + 13 TO ;
     oDlg:nTop + 6, oDlg:nLeft + 50 ;
     COLOR oDlg:cColor

   DispOutAt( oDlg:nTop + 6, oDlg:nLeft + 12, Chr( 195 ), oDlg:cColor )
   DispOutAt( oDlg:nTop + 6, oDlg:nLeft + 51, Chr( 180 ), oDlg:cColor )

   /* Display labels */

   DispOutAt( oDlg:nTop + 1, oDlg:nLeft + 13, "Alias:                Record:         ", oDlg:cColor )
   DispOutAt( oDlg:nTop + 2, oDlg:nLeft + 13, "   BOF:         Deleted:              ", oDlg:cColor )
   DispOutAt( oDlg:nTop + 3, oDlg:nLeft + 13, "   EOF:           Found:              ", oDlg:cColor )
   DispOutAt( oDlg:nTop + 4, oDlg:nLeft + 13, "Filter:                               ", oDlg:cColor )
   DispOutAt( oDlg:nTop + 5, oDlg:nLeft + 13, "   Key:                               ", oDlg:cColor )

   /* Stabilize browse */

   aBrw[ 1 ]:ForceStable()
   aBrw[ 2 ]:ForceStable()
   aBrw[ 3 ]:ForceStable()
   aBrw[ 2 ]:Dehilite()
   aBrw[ 3 ]:Dehilite()

   UpdateInfo( oDlg, Alias() )

return
dbgwa.prg165
STATIC PROCEDUREDlgWorkAreaKey( nKey, oDlg, aBrw, aAlias, aStruc, aInfo )
static procedure DlgWorkAreaKey( nKey, oDlg, aBrw, aAlias, aStruc, aInfo )

   local oDebug := __Dbg()
   local nAlias

   if nKey == K_TAB .or. nKey == K_SH_TAB
      aBrw[ oDebug:nWaFocus ]:Dehilite()
      oDebug:nWaFocus += iif( nKey == K_TAB, 1, -1 )
      if oDebug:nWaFocus < 1
         oDebug:nWaFocus := 3
      endif
      if oDebug:nWaFocus > 3
         oDebug:nWaFocus := 1
      endif
      aBrw[ oDebug:nWaFocus ]:Hilite()
      return
   endif

   do case
   case oDebug:nWaFocus == 1
      nAlias := aBrw[ 1 ]:Cargo
      WorkAreasKeyPressed( nKey, aBrw[ 1 ], Len( aAlias ) )
      if nAlias != aBrw[ 1 ]:Cargo
         aBrw[ 2 ]:GoTop()
         aBrw[ 2 ]:Invalidate()
         aBrw[ 2 ]:ForceStable()
         aInfo := ( aAlias[ aBrw[ 1 ]:Cargo ][ 1 ] )->( DbfInfo( aInfo ) )
         aBrw[ 3 ]:Configure()
         aBrw[ 2 ]:Invalidate()
         aBrw[ 2 ]:RefreshAll()
         aBrw[ 2 ]:ForceStable()
         aBrw[ 2 ]:Dehilite()
         aBrw[ 3 ]:GoTop()
         aBrw[ 3 ]:Invalidate()
         aBrw[ 3 ]:ForceStable()
         aStruc := ( aAlias[ aBrw[ 1 ]:Cargo ][ 1 ] )->( DbStruct() )
         aBrw[ 3 ]:Configure()
         aBrw[ 3 ]:Invalidate()
         aBrw[ 3 ]:RefreshAll()
         aBrw[ 3 ]:ForceStable()
         aBrw[ 3 ]:Dehilite()
         UpdateInfo( oDlg, aAlias[ aBrw[ 1 ]:Cargo ][ 2 ] )
      endif
   case oDebug:nWaFocus == 2
      WorkAreasKeyPressed( nKey, aBrw[ 2 ], Len( aInfo ) )
   case oDebug:nWaFocus == 3
      WorkAreasKeyPressed( nKey, aBrw[ 3 ], Len( aStruc ) )
   endcase

return
dbgwa.prg216
STATIC PROCEDUREWorkAreasKeyPressed( nKey, oBrw, nTotal )
static procedure WorkAreasKeyPressed( nKey, oBrw, nTotal )

   do case
   case nKey == K_UP

      if oBrw:Cargo > 1
         oBrw:Cargo--
         oBrw:RefreshCurrent()
         oBrw:Up()
         oBrw:ForceStable()
      endif

   case nKey == K_DOWN

      if oBrw:Cargo < nTotal
         oBrw:Cargo++
         oBrw:RefreshCurrent()
         oBrw:Down()
         oBrw:ForceStable()
      endif

   case nKey == K_HOME .OR. nKey == K_CTRL_PGUP .OR. nKey == K_CTRL_HOME

      if oBrw:Cargo > 1
         oBrw:Cargo := 1
         oBrw:GoTop()
         oBrw:ForceStable()
      endif

   case nKey == K_END .OR. nKey == K_CTRL_PGDN .OR. nKey == K_CTRL_END

      if oBrw:Cargo < nTotal
         oBrw:Cargo := nTotal
         oBrw:GoBottom()
         oBrw:ForceStable()
      endif

   endcase

return
dbgwa.prg267
STATIC FUNCTIONDbfInfo( aInfo )
static function DbfInfo( aInfo )

   local nFor
   local xType
   local xValue
   local cValue

   aInfo := {}

   AAdd( aInfo, "[" + LTrim( Str( Select( Alias() ) ) ) + "] " + Alias() )
   AAdd( aInfo, Space( 4 ) + "Current Driver" )
   AAdd( aInfo, Space( 8 ) + rddName() )
   AAdd( aInfo, Space( 4 ) + "Workarea Information" )
   AAdd( aInfo, Space( 8 ) + "Select Area: " + LTrim( Str( Select() ) ) )
   AAdd( aInfo, Space( 8 ) + "Record Size: " + LTrim( Str( Recsize() ) ) )
   AAdd( aInfo, Space( 8 ) + "Header Size: " + LTrim( Str( Header() ) ) )
   AAdd( aInfo, Space( 8 ) + "Field Count: " + LTrim( Str( FCount() ) ) )
   AAdd( aInfo, Space( 8 ) + "Last Update: " + DToC( lUpdate() ) )
   AAdd( aInfo, Space( 8 ) + "Index order: " + LTrim( Str( IndexOrd() ) ) )
   AAdd( aInfo, Space( 4 ) + "Current Record" )

   for nFor := 1 to FCount()

      xValue := FieldGet( nFor )
      xType  := ValType( xValue )

      do case
      case xType $ "CM" ; cValue := xValue
      case xType == "N" ; cValue := LTrim( Str( xValue ) )
      case xType == "D" ; cValue := DToC( xValue )
      case xType == "L" ; cValue := iif( xValue, ".T.", ".F." )
      case xType == "A" ; cValue := "Array"
      otherwise         ; cValue := "Error"
      endcase

      AAdd( aInfo, Space( 8 ) + PadR( FieldName( nFor ), 10) + " = " + PadR( cValue, 17 ) )

   next

return aInfo
dbgwa.prg308
STATIC PROCEDUREUpdateInfo( oDlg, cAlias )
static procedure UpdateInfo( oDlg, cAlias )

   local nOldArea

   if Empty( cAlias )
      return
   endif
   
   nOldArea := Select()
   
   dbSelectArea( cAlias )

   DispOutAt( oDlg:nTop + 1, oDlg:nLeft + 20, PadR( cAlias, 11 ), oDlg:cColor )
   DispOutAt( oDlg:nTop + 1, oDlg:nLeft + 42,;
              PadR( LTrim( Str( RecNo() ) ) + "/" + LTrim( Str( LastRec() ) ), 9 ),;
              oDlg:cColor )

   DispOutAt( oDlg:nTop + 2, oDlg:nLeft + 21, iif( Bof(), "Yes", "No " ), oDlg:cColor )
   DispOutAt( oDlg:nTop + 2, oDlg:nLeft + 38, iif( Deleted(), "Yes", "No " ), oDlg:cColor )
   DispOutAt( oDlg:nTop + 3, oDlg:nLeft + 21, iif( Eof(), "Yes", "No " ), oDlg:cColor )
   DispOutAt( oDlg:nTop + 3, oDlg:nLeft + 38, iif( Found(), "Yes", "No " ), oDlg:cColor )
   DispOutAt( oDlg:nTop + 4, oDlg:nLeft + 21, PadR( dbFilter(), 29 ), oDlg:cColor )
   DispOutAt( oDlg:nTop + 5, oDlg:nLeft + 21, PadR( ordKey(), 29 ), oDlg:cColor )

   dbSelectArea( nOldArea )

return
dbgwa.prg349
debugger.prg
TypeFunctionSourceLine
PROCEDURE__dbgAltDEntry()
PROCEDURE __dbgAltDEntry()

   /* do not activate the debugger imediatelly because the module
      where ALTD() was called can have no debugger info - stop
      on first LINE with debugged info
    */
   __dbgINVOKEDEBUG( Set( _SET_DEBUG ) )

   RETURN
debugger.prg111
PROCEDURE__dbgEntry( nMode, uParam1, uParam2, uParam3, uParam4, uParam5 )
PROCEDURE __dbgEntry( nMode, uParam1, uParam2, uParam3, uParam4, uParam5 )

   LOCAL lStartup

   DO CASE
   CASE nMode == HB_DBG_GETENTRY

      __dbgSetEntry()

   CASE nMode == HB_DBG_ACTIVATE

      IF ( lStartup := ( s_oDebugger == NIL ) )
         s_oDebugger := HBDebugger():New()
         s_oDebugger:pInfo := uParam1
      ENDIF
      s_oDebugger:nProcLevel := uParam2
      s_oDebugger:aCallStack := uParam3
      s_oDebugger:aModules := uParam4
      s_oDebugger:aBreakPoints := uParam5
      IF lStartup
         IF s_oDebugger:lRunAtStartup
            __dbgSetGo( uParam1 )
            RETURN
         ENDIF
      ENDIF
      s_oDebugger:lGo := .F.
      s_oDebugger:Activate()

   ENDCASE

   RETURN

CREATE CLASS HBDebugger

   VAR pInfo
   VAR aWindows          INIT {}
   VAR nCurrentWindow    INIT 1
   VAR oPullDown

   VAR oWndCode
   VAR oWndCommand
   VAR oWndStack
   VAR oWndVars

   VAR oBar
   VAR oBrwText
   VAR cPrgName
   VAR oBrwStack
   VAR oBrwVars
   VAR aVars             INIT {}

   VAR nAppDispCount
   VAR nAppLastKey
   VAR bAppInkeyAfter
   VAR bAppInkeyBefore
   VAR bAppClassScope

   VAR nAppDirCase
   VAR nAppFileCase
   VAR oAppGetList
   VAR nAppTypeAhead

   VAR nMaxRow
   VAR nMaxCol

   VAR hUserWindow
   VAR hDebuggerWindow
   VAR lDebuggerWindowIsOpen INIT .F.

   VAR aBreakPoints      INIT {}
   VAR aCallStack        INIT {}    // stack of procedures with debug info
   VAR aProcStack        INIT {}    // stack of all procedures
   VAR nProcLevel                   // procedure level where the debugger is currently
   VAR aModules          INIT {}    // array of modules with static and GLOBAL variables
   VAR aWatch            INIT {}
   VAR aColors           INIT { "W+/BG", "N/BG", "R/BG", "N+/BG", "W+/B", "GR+/B", "W/B", "N/W", "R/W", "N/BG", "R/BG" }

   VAR aLastCommands
   VAR nCommand
   VAR oGetListCommand

   VAR lAnimate          INIT .F.
   VAR lEnd              INIT .F.
   VAR lCaseSensitive    INIT .F.
   VAR lMonoDisplay      INIT .F.
   VAR lSortVars         INIT .F.

   VAR cSearchString     INIT ""
   VAR cPathForFiles
   VAR cSettingsFileName INIT "init.cld"
   VAR aPathDirs

   VAR nTabWidth         INIT 4
   VAR nSpeed            INIT 0

   VAR lShowPublics      INIT .F.
   VAR lShowPrivates     INIT .F.
   VAR lShowStatics      INIT .F.
   VAR lShowLocals       INIT .F.
   VAR lShowGlobals      INIT .F.
   VAR lShowAllGlobals   INIT .F.
   VAR lAll              INIT .F.
   VAR lShowCallStack    INIT .F.
   VAR lGo                          // stores if GO was requested
   VAR lActive           INIT .F.
   VAR lCBTrace          INIT .T.   // stores if codeblock tracing is allowed
   VAR oBrwPnt
   VAR oWndPnt
   VAR lPPO              INIT .F.
   VAR lRunAtStartup     INIT .T.   // Clipper compatible
   VAR lLineNumbers      INIT .T.
   VAR nHelpPage         INIT 1
   VAR nWaFocus          INIT 1
debugger.prg122
METHODNew()
   METHOD New()
debugger.prg236
METHODActivate()
   METHOD Activate()
debugger.prg237
METHODAll()
   METHOD All()
debugger.prg239
METHOD ANIMATE() INLINE IIF( ::LANIMATE, :Step(), NIL )
   METHOD Animate() INLINE iif( ::lAnimate, ::Step(), NIL )
debugger.prg241
METHODBarDisplay()
   METHOD BarDisplay()
debugger.prg243
METHODBuildCommandWindow()
   METHOD BuildCommandWindow()
debugger.prg244
METHODBuildBrowseStack()
   METHOD BuildBrowseStack()
debugger.prg245
METHODCallStackProcessKey( nKey )
   METHOD CallStackProcessKey( nKey )
debugger.prg247
METHOD CLRMODAL() INLINEiif( ::lMonoDisplay, "N/W, W+/W, W/N, W+/N", "N/W, R/W, N/BG, R/BG" )
   METHOD ClrModal() INLINE iif( ::lMonoDisplay, "N/W, W+/W, W/N, W+/N",;
                                "N/W, R/W, N/BG, R/BG" )
debugger.prg248
METHODCodeblockTrace()
   METHOD CodeblockTrace()
debugger.prg251
METHODCodeWindowProcessKey( nKey )
   METHOD CodeWindowProcessKey( nKey )
debugger.prg252
METHODColors()
   METHOD Colors()
debugger.prg253
METHODCommandWindowProcessKey( nKey )
   METHOD CommandWindowProcessKey( nKey )
debugger.prg254
METHODDoCommand( cCommand )
   METHOD DoCommand( cCommand )
debugger.prg255
METHODDoScript( cFileName )
   METHOD DoScript( cFileName )
debugger.prg256
METHODEditColor( nColor, oBrwColors )
   METHOD EditColor( nColor, oBrwColors )
debugger.prg257
METHODEditSet( nSet, oBrwSets )
   METHOD EditSet( nSet, oBrwSets )
debugger.prg258
METHODEditVar( nVar )
   METHOD EditVar( nVar )
debugger.prg259
METHODExit() INLINE ::lEnd := .T.
   METHOD Exit() INLINE ::lEnd := .T.
debugger.prg260
METHODFindNext()
   METHOD FindNext()
debugger.prg261
METHODFindPrevious()
   METHOD FindPrevious()
debugger.prg262
METHODGetExprValue( xExpr, lValid )
   METHOD GetExprValue( xExpr, lValid )
debugger.prg263
METHODGetSourceFiles()
   METHOD GetSourceFiles()
debugger.prg264
METHODGlobal()
   METHOD Global()
debugger.prg266
METHODGo()
   METHOD Go()
debugger.prg268
METHODGoToLine( nLine )
   METHOD GoToLine( nLine )
debugger.prg269
METHODHandleEvent()
   METHOD HandleEvent()
debugger.prg270
METHODHide()
   METHOD Hide()
debugger.prg271
METHODHideCallStack()
   METHOD HideCallStack()
debugger.prg272
METHODHideVars()
   METHOD HideVars()
debugger.prg273
METHODInputBox( cMsg, uValue, bValid, lEditable )
   METHOD InputBox( cMsg, uValue, bValid, lEditable )
debugger.prg274
METHODInspect( uValue, cValueName )
   METHOD Inspect( uValue, cValueName )
debugger.prg275
METHODIsValidStopLine( cName, nLine )
   METHOD IsValidStopLine( cName, nLine )
debugger.prg276
METHODListBox( cCaption, aItems )
   METHOD ListBox( cCaption, aItems )
debugger.prg277
METHODLoadColors()
   METHOD LoadColors()
debugger.prg278
METHODLoadSettings()
   METHOD LoadSettings()
debugger.prg279
METHODLoadVars()
   METHOD LoadVars()
debugger.prg280
METHODLoadCallStack()
   METHOD LoadCallStack()
debugger.prg281
METHODLocal()
   METHOD Local()
debugger.prg283
METHODLocate( nMode, cValue )
   METHOD Locate( nMode, cValue )
debugger.prg285
METHODMonoDisplay()
   METHOD MonoDisplay()
debugger.prg287
METHODNextWindow()
   METHOD NextWindow()
debugger.prg288
METHODOpen()
   METHOD Open()
debugger.prg289
METHODOpenPPO()
   METHOD OpenPPO()
debugger.prg290
METHOD RESUME() INLINE :ShowCodeLine( 1 )
   METHOD Resume() INLINE ::ShowCodeLine( 1 )
debugger.prg291
METHODOSShell()
   METHOD OSShell()
debugger.prg292
METHODPathForFiles( cPathForFiles )
   METHOD PathForFiles( cPathForFiles )
debugger.prg293
METHODPrevWindow()
   METHOD PrevWindow()
debugger.prg295
METHODPrivate()
   METHOD Private()
debugger.prg296
METHODPublic()
   METHOD Public()
debugger.prg297
METHODQuit()
   METHOD Quit()
debugger.prg298
METHODRefreshVars()
   METHOD RefreshVars()
debugger.prg299
METHODRestoreAppScreen()
   METHOD RestoreAppScreen()
debugger.prg300
METHODRestoreAppState()
   METHOD RestoreAppState()
debugger.prg301
METHODRestoreSettings()
   METHOD RestoreSettings()
debugger.prg302
METHOD RUNATSTARTUP() INLINE ::LRUNATSTARTUP := ::OPULLDOWNGetItemByIdent( "ALTD" ):checked := !::lRunAtStartup
   METHOD RunAtStartup() INLINE ::lRunAtStartup := ::oPullDown:GetItemByIdent( "ALTD" ):checked := !::lRunAtStartup
debugger.prg303
METHODSaveAppScreen()
   METHOD SaveAppScreen()
debugger.prg304
METHODSaveAppState()
   METHOD SaveAppState()
debugger.prg305
METHODSaveSettings()
   METHOD SaveSettings()
debugger.prg306
METHODShow()
   METHOD Show()
debugger.prg307
METHODShowAllGlobals()
   METHOD ShowAllGlobals()
debugger.prg308
METHODShowAppScreen()
   METHOD ShowAppScreen()
debugger.prg309
METHODShowCallStack()
   METHOD ShowCallStack()
debugger.prg310
METHODShowCodeLine( nProc )
   METHOD ShowCodeLine( nProc )
debugger.prg311
METHODShowHelp( nTopic )
   METHOD ShowHelp( nTopic )
debugger.prg312
METHODShowVars()
   METHOD ShowVars()
debugger.prg313
METHODRedisplayBreakpoints()
   METHOD RedisplayBreakpoints()
debugger.prg314
METHODLocatePrgPath( cPrgName )
   METHOD LocatePrgPath( cPrgName )
debugger.prg315
METHOD SORT() INLINE ASORT( ::AVARS,,, { | X, Y | X[ 1 ] < Y[ 1 ] } ), ::LSORTVARS := .T., IIF( ::OBRWVARS != NIL, ::OBRWVARS:REFRESHALL(), NIL ), IIF( ::OWNDVARS != NIL .AND. ::OWNDVARS:LVISIBLE, IIF( !::LGO, ::OBRWVARSForceStable(), NIL ), NIL )
   METHOD Sort() INLINE ASort( ::aVars,,, { | x, y | x[ 1 ] < y[ 1 ] } ),;
                        ::lSortVars := .T.,;
                        iif( ::oBrwVars != NIL, ::oBrwVars:RefreshAll(), NIL ),;
                        iif( ::oWndVars != NIL .AND. ::oWndVars:lVisible, iif( !::lGo, ::oBrwVars:ForceStable(), NIL ), NIL )
debugger.prg316
METHOD SPEED() INLINE ::NSPEED := ::INPUTBOX( "STEPdelay (in tenths of a second)", ::nSpeed )
   METHOD Speed() INLINE ::nSpeed := ::InputBox( "Step delay (in tenths of a second)", ::nSpeed )
debugger.prg321
METHODStack()
   METHOD Stack()
debugger.prg323
METHODStatic()
   METHOD Static()
debugger.prg324
METHODStep()
   METHOD Step()
debugger.prg326
METHOD TABWIDTH() INLINE ::NTABWIDTH := ::INPUTBOX( "TAB WIDTH", ::NTABWIDTH ), ::OBRWTEXT:NTABWIDTH := ::NTABWIDTH, ::OBRWTEXTRefreshAll()
   METHOD TabWidth() INLINE ;
          ::nTabWidth := ::InputBox( "Tab width", ::nTabWidth ),;
          ::oBrwText:nTabWidth := ::nTabWidth, ::oBrwText:RefreshAll()
debugger.prg328
METHODToggleBreakPoint()
   METHOD ToggleBreakPoint()
debugger.prg332
METHODTrace()
   METHOD Trace()
debugger.prg334
METHODToCursor()
   METHOD ToCursor()
debugger.prg336
METHODNextRoutine()
   METHOD NextRoutine()
debugger.prg337
METHODViewSets()
   METHOD ViewSets()
debugger.prg338
METHODWndVarsLButtonDown( nMRow, nMCol )
   METHOD WndVarsLButtonDown( nMRow, nMCol )
debugger.prg339
METHODLineNumbers( lLineNumbers )
   METHOD LineNumbers( lLineNumbers ) // Toggles numbering of source code lines
debugger.prg340
METHODRemoveWindow()
   METHOD RemoveWindow()
debugger.prg341
METHODSearchLine()
   METHOD SearchLine()
debugger.prg342
METHOD TOGGLEANIMATE() INLINE ::OPULLDOWNGetItemByIdent( "ANIMATE" ):checked := ::lAnimate := ! ::lAnimate
   METHOD ToggleAnimate() INLINE ::oPullDown:GetItemByIdent( "ANIMATE" ):checked := ::lAnimate := ! ::lAnimate
debugger.prg343
METHOD TOGGLECASESENSITIVE() INLINE ::OPULLDOWNGetItemByIdent( "CASE" ):checked := ::lCaseSensitive := ! ::lCaseSensitive
   METHOD ToggleCaseSensitive() INLINE ::oPullDown:GetItemByIdent( "CASE" ):checked := ::lCaseSensitive := ! ::lCaseSensitive
debugger.prg344
METHOD SHOWWORKAREAS() INLINE__dbgShowWorkAreas( Self )
   METHOD ShowWorkAreas() INLINE __dbgShowWorkAreas( Self )
debugger.prg345
METHODTracepointAdd( cExpr )
   METHOD TracepointAdd( cExpr )
debugger.prg347
METHODWatchpointAdd( cExpr )
   METHOD WatchpointAdd( cExpr )
debugger.prg348
METHODWatchpointDel( nPos )
   METHOD WatchpointDel( nPos )
debugger.prg349
METHODWatchpointsShow()
   METHOD WatchpointsShow()
debugger.prg350
METHODWatchpointsHide()
   METHOD WatchpointsHide()
debugger.prg351
METHODWatchpointEdit( nVar )
   METHOD WatchpointEdit( nVar )
debugger.prg352
METHODWatchpointInspect( nPos )
   METHOD WatchpointInspect( nPos )
debugger.prg353
METHODWatchGetInfo( nWatch )
   METHOD WatchGetInfo( nWatch )
debugger.prg354
METHODVarGetInfo( aVar )
   METHOD VarGetInfo( aVar )
debugger.prg356
METHODVarGetValue( aVar )
   METHOD VarGetValue( aVar )
debugger.prg357
METHODVarSetValue( aVar, uValue )
   METHOD VarSetValue( aVar, uValue )
debugger.prg358
METHODResizeWindows( oWindow )
   METHOD ResizeWindows( oWindow )
debugger.prg360
METHOD NOTSUPPORTED() INLINEAlert( "Not implemented yet!" )
   METHOD NotSupported() INLINE Alert( "Not implemented yet!" )
debugger.prg361
METHODOpenDebuggerWindow()
   METHOD OpenDebuggerWindow()
debugger.prg363
METHODCloseDebuggerWindow()
   METHOD CloseDebuggerWindow()

ENDCLASS
debugger.prg364
HBDEBUGGER:METHODNew() CLASS HBDebugger
METHOD New() CLASS HBDebugger

   s_oDebugger := Self

   /* default the search path for files to the current directory
      that way if the source is in the same directory it will still be found even if the application
      changes the current directory with the SET DEFAULT command. */
   ::cPathForFiles := GetEnv( "HB_DBG_PATH" )
   IF Empty( ::cPathForFiles )
      ::cPathForFiles := GetEnv( "PATH" )
   ENDIF
   ::aPathDirs := PathToArray( ::cPathForFiles )

   ::lGo := ::lRunAtStartup

   /* Store the initial screen dimensions for now */
   ::nMaxRow := MaxRow()
   ::nMaxCol := MaxCol()

   ::oPullDown := __dbgBuildMenu( Self )

   ::oWndCode             := HBDbWindow():New( 1, 0, ::nMaxRow - 6, ::nMaxCol )
   ::oWndCode:Cargo       := { ::oWndCode:nTop, ::oWndCode:nLeft }
   ::oWndCode:bKeyPressed := { | nKey | ::CodeWindowProcessKey( nKey ) }
   ::oWndCode:bGotFocus   := { || ::oGetListCommand:SetFocus(), SetCursor( SC_SPECIAL1 ), ;
                                  SetPos( ::oWndCode:Cargo[ 1 ],::oWndCode:Cargo[ 2 ] ) }
   ::oWndCode:bLostFocus  := { || ::oWndCode:Cargo[ 1 ] := Row(), ::oWndCode:Cargo[ 2 ] := Col(), ;
                                  SetCursor( SC_NONE ) }

   AAdd( ::aWindows, ::oWndCode )

   ::BuildCommandWindow()
   ::BuildBrowseStack()

   IF File( ::cSettingsFileName )
      ::LoadSettings()
      ::lGo := ::lRunAtStartup // Once again after settings file is loaded
   ENDIF

   RETURN Self
debugger.prg369
HBDEBUGGER:METHODOpenDebuggerWindow() CLASS HBDebugger
METHOD OpenDebuggerWindow() CLASS HBDebugger

   IF !::lDebuggerWindowIsOpen
      ::hUserWindow := hb_gtInfo( HB_GTI_GETWIN )
      IF ::hDebuggerWindow == NIL
         ::hDebuggerWindow := hb_gtInfo( HB_GTI_GETWIN, ;
                                 { "Debugger", DEBUGGER_MINROW, DEBUGGER_MINCOL, ;
                                   DEBUGGER_MAXROW, DEBUGGER_MAXCOL } )
      ELSE
         hb_gtInfo( HB_GTI_SETWIN, ::hDebuggerWindow )
      ENDIF
      ::lDebuggerWindowIsOpen := .T.
   ENDIF

   RETURN NIL
debugger.prg410
HBDEBUGGER:METHODCloseDebuggerWindow() CLASS HBDebugger
METHOD CloseDebuggerWindow() CLASS HBDebugger

   IF ::lDebuggerWindowIsOpen
      ::hDebuggerWindow := hb_gtInfo( HB_GTI_GETWIN )
      hb_gtInfo( HB_GTI_SETWIN, ::hUserWindow )
      ::lDebuggerWindowIsOpen := .F.
   ENDIF

   RETURN NIL
debugger.prg427
HBDEBUGGER:METHODActivate() CLASS HBDebugger
METHOD Activate() CLASS HBDebugger

   ::LoadCallStack()
   ::SaveAppState()

   IF ! ::lActive
      ::lActive := .T.
      ::Show()
      IF ::lShowCallStack
         ::ShowCallStack()
      ENDIF
   ELSE
      ::SaveAppScreen()
   ENDIF

   ::LoadVars()
   ::ShowVars()

   IF ::oWndPnt != NIL
      ::WatchpointsShow()
   ENDIF

   // show the topmost procedure
   ::ShowCodeLine( 1 ) // ::aCallStack[ 1 ][ CSTACK_LINE ], ::aCallStack[ 1 ][ CSTACK_MODULE ] )
   ::HandleEvent()

   RETURN NIL
debugger.prg438
HBDEBUGGER:METHODAll() CLASS HBDebugger
METHOD All() CLASS HBDebugger

   ::lShowPublics := ::lShowPrivates := ::lShowStatics := ;
   ::lShowLocals := ::lShowGlobals := ::lAll := ! ::lAll

   ::RefreshVars()

   RETURN NIL
debugger.prg467
HBDEBUGGER:METHODBarDisplay() CLASS HBDebugger
METHOD BarDisplay() CLASS HBDebugger

   LOCAL cClrItem   := __DbgColors()[ 8 ]
   LOCAL cClrHotKey := __DbgColors()[ 9 ]

   DispBegin()

   SetColor( cClrItem )

   @ ::nMaxRow, 0 CLEAR TO ::nMaxRow, ::nMaxCol

   DispOutAt( ::nMaxRow,  0, "F1-Help F2-Zoom F3-Repeat F4-User F5-Go F6-WA F7-Here F8-Step F9-BkPt F10-Trace", cClrItem )
   DispOutAt( ::nMaxRow,  0, "F1", cClrHotKey )
   DispOutAt( ::nMaxRow,  8, "F2", cClrHotKey )
   DispOutAt( ::nMaxRow, 16, "F3", cClrHotKey )
   DispOutAt( ::nMaxRow, 26, "F4", cClrHotKey )
   DispOutAt( ::nMaxRow, 34, "F5", cClrHotKey )
   DispOutAt( ::nMaxRow, 40, "F6", cClrHotKey )
   DispOutAt( ::nMaxRow, 46, "F7", cClrHotKey )
   DispOutAt( ::nMaxRow, 54, "F8", cClrHotKey )
   DispOutAt( ::nMaxRow, 62, "F9", cClrHotKey )
   DispOutAt( ::nMaxRow, 70, "F10", cClrHotKey )

   DispEnd()

   RETURN NIL
debugger.prg476
HBDEBUGGER:METHODBuildBrowseStack() CLASS HBDebugger
METHOD BuildBrowseStack() CLASS HBDebugger

   IF ::oBrwStack == NIL
      ::oBrwStack := HBDbBrowser():New( 2, ::nMaxCol - 14, ::nMaxRow - 7, ::nMaxCol - 1 )
      ::oBrwStack:ColorSpec := ::aColors[ 3 ] + "," + ::aColors[ 4 ] + "," + ::aColors[ 5 ]
      ::oBrwStack:goTopBlock := { || ::oBrwStack:Cargo := 1 }
      ::oBrwStack:goBottomBlock := { || ::oBrwStack:Cargo := Len( ::aProcStack ) }
      ::oBrwStack:skipBlock := { | nSkip, nOld | nOld := ::oBrwStack:Cargo,;
                              ::oBrwStack:Cargo += nSkip,;
                              ::oBrwStack:Cargo := Min( Max( ::oBrwStack:Cargo, 1 ),;
                              Len( ::aProcStack ) ), ::oBrwStack:Cargo - nOld }

      ::oBrwStack:Cargo := 1 // Actual highligthed row

      ::oBrwStack:AddColumn( TBColumnNew( "", { || iif( Len( ::aProcStack ) > 0,;
            PadC( ::aProcStack[ ::oBrwStack:Cargo ][ CSTACK_FUNCTION ], 14 ), Space( 14 ) ) } ) )
   ENDIF

   RETURN NIL
debugger.prg504
HBDEBUGGER:METHODBuildCommandWindow() CLASS HBDebugger
METHOD BuildCommandWindow() CLASS HBDebugger

   LOCAL GetList := {}
   LOCAL oGet
   LOCAL cCommand

   ::oWndCommand := HBDbWindow():New( ::nMaxRow - 5, 0, ::nMaxRow - 1, ::nMaxCol, "Command" )

   ::oWndCommand:bGotFocus   := { || ::oGetListCommand:SetFocus(), SetCursor( SC_NORMAL ) }
   ::oWndCommand:bLostFocus  := { || SetCursor( SC_NONE ) }
   ::oWndCommand:bKeyPressed := { | nKey | ::CommandWindowProcessKey( nKey ) }
   ::oWndCommand:bPainted    := { || DispOutAt( ::oWndCommand:nBottom - 1,;
                             ::oWndCommand:nLeft + 1, "> ", __DbgColors()[ 2 ] ),;
                             oGet:ColorDisp( Replicate( __DbgColors()[ 2 ] + ",", 5 ) ),;
                             hb_ClrArea( ::oWndCommand:nTop + 1, ::oWndCommand:nLeft + 1,;
                             ::oWndCommand:nBottom - 2, ::oWndCommand:nRight - 1,;
                             iif( ::lMonoDisplay, 15, hb_ColorToN( __DbgColors()[ 2 ] ) ) ) }
   AAdd( ::aWindows, ::oWndCommand )

   ::aLastCommands := { "" }
   ::nCommand := 1

   cCommand := Space( ::oWndCommand:nRight - ::oWndCommand:nLeft - 3 )
   // We don't use the GET command here to avoid the painting of the GET
   AAdd( GetList, oGet := Get():New( ::oWndCommand:nBottom - 1, ::oWndCommand:nLeft + 3,;
         { | u | iif( PCount() > 0, cCommand := u, cCommand ) }, "cCommand" ) )
   oGet:ColorSpec := Replicate( __DbgColors()[ 2 ] + ",", 5 )
   ::oGetListCommand := HBGetList():New( GetList )

   RETURN NIL
debugger.prg525
HBDEBUGGER:METHODCallStackProcessKey( nKey ) CLASS HBDebugger
METHOD CallStackProcessKey( nKey ) CLASS HBDebugger

   LOCAL n
   LOCAL nSkip
   LOCAL lUpdate := .F.

   DO CASE
   CASE nKey == K_HOME .OR. nKey == K_CTRL_PGUP .OR. nKey == K_CTRL_HOME

      IF ::oBrwStack:Cargo > 1
         ::oBrwStack:GoTop()
         ::oBrwStack:ForceStable()
         lUpdate := .T.
      ENDIF

   CASE nKey == K_END .OR. nKey == K_CTRL_PGDN .OR. nKey == K_CTRL_END

      IF ::oBrwStack:Cargo < Len( ::aProcStack )
         ::oBrwStack:GoBottom()
         ::oBrwStack:ForceStable()
         lUpdate := .T.
      ENDIF

   CASE nKey == K_UP

      IF ::oBrwStack:Cargo > 1
         ::oBrwStack:Up()
         ::oBrwStack:ForceStable()
         lUpdate := .T.
      ENDIF

   CASE nKey == K_DOWN

      IF ::oBrwStack:Cargo < Len( ::aProcStack )
         ::oBrwStack:Down()
         ::oBrwStack:ForceStable()
         lUpdate := .T.
      ENDIF

   CASE nKey == K_PGUP

      ::oBrwStack:PageUp()
      ::oBrwStack:ForceStable()
      lUpdate := .T.

   CASE nKey == K_PGDN

      ::oBrwStack:PageDown()
      ::oBrwStack:ForceStable()
      lUpdate := .T.

   CASE nKey == K_LBUTTONDOWN

      IF ( nSkip := MRow() - ::oWndStack:nTop - ::oBrwStack:RowPos ) != 0
         IF nSkip > 0
            FOR n := 1 TO nSkip
               ::oBrwStack:Down()
               ::oBrwStack:Stabilize()
            NEXT
         ELSE
            FOR n := 1 TO nSkip + 2 STEP -1
               ::oBrwStack:Up()
               ::oBrwStack:Stabilize()
            NEXT
         ENDIF
         ::oBrwStack:ForceStable()
      ENDIF
      lUpdate := .T.

   ENDCASE

   IF lUpdate
      IF ::oWndVars != NIL .AND. ::oWndVars:lVisible
         ::LoadVars()
         ::ShowVars()
      ENDIF

      // jump to source line for a function

      /*
      IF ::aCallStack[ ::oBrwStack:Cargo ][ CSTACK_LINE ] != NIL
         ::ShowCodeLine( ::aCallStack[ ::oBrwStack:Cargo ][ CSTACK_LINE ], ::aCallStack[ ::oBrwStack:Cargo ][ CSTACK_MODULE ] )
      ELSE
         ::GotoLine( 1 )
      ENDIF
      */

      ::ShowCodeLine( ::oBrwStack:Cargo )
   ENDIF

   RETURN NIL
debugger.prg557
HBDEBUGGER:METHODCodeblockTrace()
METHOD CodeblockTrace()

   ::oPullDown:GetItemByIdent( "CODEBLOCK" ):checked := ::lCBTrace := ! ::lCBTrace
   __dbgSetCBTrace( ::pInfo, ::lCBTrace )

   RETURN NIL
debugger.prg650
HBDEBUGGER:METHODCodeWindowProcessKey( nKey ) CLASS HBDebugger
METHOD CodeWindowProcessKey( nKey ) CLASS HBDebugger

   IF ::oBrwText != NIL

      DO CASE
      CASE nKey == K_HOME .OR. nKey == K_CTRL_PGUP .OR. nKey == K_CTRL_HOME

         ::oBrwText:GoTop()
         IF ::oWndCode:lFocused
            SetCursor( SC_SPECIAL1 )
         ENDIF

      CASE nKey == K_END .OR. nKey == K_CTRL_PGDN .OR. nKey == K_CTRL_END

         ::oBrwText:GoBottom()
         ::oBrwText:nCol := ::oWndCode:nLeft + 1
         ::oBrwText:nFirstCol := ::oWndCode:nLeft + 1
         SetPos( Row(), ::oWndCode:nLeft + 1 )
         IF ::oWndCode:lFocused
            SetCursor( SC_SPECIAL1 )
         ENDIF

      CASE nKey == K_LEFT
         ::oBrwText:Left()

      CASE nKey == K_RIGHT
         ::oBrwText:Right()

      CASE nKey == K_UP
         ::oBrwText:Up()

      CASE nKey == K_DOWN
         ::oBrwText:Down()

      CASE nKey == K_PGUP
         ::oBrwText:PageUp()

      CASE nKey == K_PGDN
         ::oBrwText:PageDown()

      ENDCASE
   ENDIF

   RETURN NIL
debugger.prg658
HBDEBUGGER:METHODColors() CLASS HBDebugger
METHOD Colors() CLASS HBDebugger

   LOCAL oWndColors := HBDbWindow():New( 4, 5, 16, ::nMaxCol - 5,;
                                        "Debugger Colors[1..11]", ::ClrModal() )
   LOCAL aColors := { "Border", "Text", "Text High", "Text PPO", "Text Selected",;
                      "Text High Sel.", "Text PPO Sel.", "Menu", "Menu High",;
                      "Menu Selected", "Menu High Sel." }

   LOCAL oBrwColors := HBDbBrowser():New( oWndColors:nTop + 1, oWndColors:nLeft + 1,;
                                          oWndColors:nBottom - 1, oWndColors:nRight - 1 )
   LOCAL nWidth := oWndColors:nRight - oWndColors:nLeft - 1
   LOCAL oCol

   IF ::lMonoDisplay
      Alert( "Monochrome display" )
      RETURN NIL
   ENDIF

   oBrwColors:Cargo := { 1, {} } // Actual highligthed row
   oBrwColors:ColorSpec := ::ClrModal()
   oBrwColors:goTopBlock := { || oBrwColors:cargo[ 1 ] := 1 }
   oBrwColors:goBottomBlock := { || oBrwColors:cargo[ 1 ] := Len( oBrwColors:cargo[ 2 ][ 1 ] ) }
   oBrwColors:skipBlock := { | nPos | ( nPos := ArrayBrowseSkip( nPos, oBrwColors ), oBrwColors:cargo[ 1 ] := ;
   oBrwColors:cargo[ 1 ] + nPos, nPos ) }

   oBrwColors:AddColumn( oCol := TBColumnNew( "", { || PadR( aColors[ oBrwColors:Cargo[ 1 ] ], 14 ) } ) )
   oCol:defColor := { 1, 2 }
   AAdd( oBrwColors:Cargo[ 2 ], aColors )
   oBrwColors:AddColumn( oCol := TBColumnNew( "",;
                       { || PadR( '"' + ::aColors[ oBrwColors:Cargo[ 1 ] ] + '"', nWidth - 15 ) } ) )
   AAdd( oBrwColors:Cargo[ 2 ], aColors )
   oCol:defColor := { 1, 3 }
   ocol:width := 50
   oBrwColors:autolite := .F.

   oWndColors:bPainted    := { || oBrwColors:ForceStable(), RefreshVarsS( oBrwColors ) }

   oWndColors:bKeyPressed := { | nKey | SetsKeyPressed( nKey, oBrwColors,;
                               Len( aColors ), oWndColors, "Debugger Colors",;
                               { || ::EditColor( oBrwColors:Cargo[ 1 ], oBrwColors ) } ) }
   oWndColors:ShowModal()

   ::LoadColors()

   RETURN NIL
debugger.prg704
HBDEBUGGER:METHODCommandWindowProcessKey( nKey ) CLASS HBDebugger
METHOD CommandWindowProcessKey( nKey ) CLASS HBDebugger

   LOCAL cCommand
   LOCAL n
   LOCAL nWidth := ::oWndCommand:nRight - ::oWndCommand:nLeft - 3

   DO CASE
   CASE nKey == K_UP .OR. nKey == K_F3

      IF ::nCommand > 1
         ::oGetListCommand:Get():Assign()
         ::aLastCommands[ ::nCommand ] := Trim( ::oGetListCommand:Get():VarGet() )
         ::nCommand--
         cCommand := PadR( ::aLastCommands[ ::nCommand ], nWidth )
         ::oGetListCommand:Get():VarPut( cCommand )
         ::oGetListCommand:Get():Buffer := cCommand
         ::oGetListCommand:Get():Pos := Len( ::aLastCommands[ ::nCommand ] ) + 1
         ::oGetListCommand:Get():Display()
      ENDIF

   CASE nKey == K_DOWN

      IF ::nCommand < Len( ::aLastCommands )
         ::oGetListCommand:Get():Assign()
         ::aLastCommands[ ::nCommand ] := Trim( ::oGetListCommand:Get():VarGet() )
         ::nCommand++
         cCommand := PadR( ::aLastCommands[ ::nCommand ], nWidth )
         ::oGetListCommand:Get():VarPut( cCommand )
         ::oGetListCommand:Get():Buffer := cCommand
         ::oGetListCommand:Get():Pos := Len( ::aLastCommands[ ::nCommand ] ) + 1
         ::oGetListCommand:Get():Display()
      ENDIF

   CASE nKey == K_ENTER

      /* We must call :Assign() before :VarGet(), because it's no longer
       * called on every change */
      ::oGetListCommand:Get():Assign()
      cCommand := Trim( ::oGetListCommand:Get():VarGet() )

      IF ! Empty( cCommand )
         IF ( n := AScan( ::aLastCommands, cCommand ) ) > 0 .AND. n < Len( ::aLastCommands )
            ADel( ::aLastCommands, n, .T. )
         ENDIF
         ::nCommand := Len( ::aLastCommands )
         ::aLastCommands[ ::nCommand ] := cCommand
         AAdd( ::aLastCommands, "" )
         ::nCommand := Len( ::aLastCommands )
         ::oWndCommand:ScrollUp( 1 )
         ::DoCommand( cCommand )
      ENDIF

      DispOutAt( ::oWndCommand:nBottom - 1, ::oWndCommand:nLeft + 1, "> ",;
         __DbgColors()[ 2 ] )
      cCommand := Space( nWidth )
      ::oGetListCommand:Get():VarPut( cCommand )
      ::oGetListCommand:Get():Buffer := cCommand
      ::oGetListCommand:Get():Pos := 1
      ::oGetListCommand:Get():Display()

   OTHERWISE
      ::oGetListCommand:GetApplyKey( nKey )
   ENDCASE

   RETURN NIL
debugger.prg751
HBDEBUGGER:METHODDoCommand( cCommand ) CLASS HBDebugger
METHOD DoCommand( cCommand ) CLASS HBDebugger

   LOCAL aCmnd[ 3 ]
   LOCAL cParam
   LOCAL cParam1 := ""
   LOCAL cResult
   LOCAL lValid
   LOCAL n

   cCommand := AllTrim( cCommand )

   DO CASE
   CASE Empty( cCommand )
      RETURN ""

   CASE starts( cCommand, "??" )
      cParam := AllTrim( SubStr( cCommand, 3 ) )
      cCommand := "??"

   CASE starts( cCommand, "?" )
      cParam := SubStr( cCommand, 2 )
      cCommand := "?"

   OTHERWISE
      IF ( n := At( " ", cCommand ) ) > 0
         cParam := AllTrim( SubStr( cCommand, n + 1 ) )
         cCommand := Left( cCommand, n - 1 )
      ENDIF
      cCommand := Upper( cCommand )

   ENDCASE

   DO CASE
   CASE cCommand == "??" .OR. cCommand == "?"
      aCmnd[ WP_TYPE ] := cCommand
      aCmnd[ WP_EXPR ] := cParam

      ::RestoreAppState()
      cResult := ::GetExprValue( cParam, @lValid )
      ::SaveAppState()

      IF aCmnd[ WP_TYPE ] == "??"
         IF lValid
            ::Inspect( aCmnd[ WP_EXPR ], cResult )
         ENDIF
         cResult := ""  //discard result
      ELSE
         IF lValid
            cResult := __dbgValToStr( cResult )
         ENDIF
      ENDIF
      ::RefreshVars()

   CASE starts( "ANIMATE", cCommand )
      IF ::lActive
         ::lAnimate := .T.
         ::Animate()
         SetCursor( SC_NORMAL )
      ENDIF

   CASE starts( "BP", cCommand )
      /* TODO: Support BP  */
      IF !Empty( cParam )
         IF ( n := At( " ", cParam ) ) > 0
            cParam1 := AllTrim( SubStr( cParam, n + 1 ) )
            cParam := Left( cParam, n - 1 )
         ELSE
            cParam1 := ::cPrgName
         ENDIF
         ::ToggleBreakPoint( Val( cParam ), strip_path( cParam1 ) )
      ELSE
         ::ToggleBreakPoint()
      ENDIF

   CASE starts( "CALLSTACK", cCommand )
      ::Stack( Upper( cParam ) == "ON" )

   /* TODO: Support DELETE ALL [TP|BP|WP], DELETE WP|TP|BP  */

   CASE starts( "DOS", cCommand )
      ::OsShell()
      SetCursor( SC_NORMAL )

   CASE starts( "FIND", cCommand )
      ::Locate( 0, cParam )

   CASE starts( "GO", cCommand )
      ::Go()

   CASE starts( "GOTO", cCommand ) .AND. Val( cParam ) > 0
      ::GoToLine( Val( cParam ) )

   CASE starts( "HELP", cCommand )
      ::ShowHelp()

   CASE starts( "INPUT", cCommand ) .AND. !Empty( cParam )
      ::DoScript( cParam )

   /* TODO: Support LIST BP|WP|TP */

   CASE starts( "MONITOR", cCommand )

      cParam := Upper( cParam )

      DO CASE
      CASE starts( "GLOBAL", cParam )
         ::Global()
      CASE starts( "LOCAL", cParam )
         ::Local()
      CASE starts( "PRIVATE", cParam )
         ::Private()
      CASE starts( "PUBLIC", cParam )
         ::Public()
      CASE starts( "SORT", cParam )
         ::Sort()
      CASE starts( "STATIC", cParam )
         ::Static()
      OTHERWISE
         cResult := "Command error"
      ENDCASE

   CASE starts( "NEXT", cCommand )
      ::FindNext()

   CASE starts( "NUM", cCommand )
      IF Upper( cParam ) == "OFF"
         ::LineNumbers( .F. )
      ELSEIF Upper( cParam ) == "ON"
         ::LineNumbers( .T. )
      ELSE
         cResult := "Command error"
      ENDIF

   CASE starts( "OPTIONS", cCommand )

      IF ( n := At( " ", cParam ) ) > 0
         cParam1 := AllTrim( SubStr( cParam, n + 1 ) )
         cParam := Left( cParam, n - 1 )
      ENDIF

      cParam := Upper( cParam )

      DO CASE
      CASE starts( "COLORS", cParam )

         IF Empty( cParam1 )
            ::Colors()
         ELSE
            cParam1 := SubStr( cParam1, At( "{", cParam1 ) + 1 )
            FOR n := 1 TO 11
               IF At( ",", cParam1 ) != 0
                  ::aColors[ n ] := ;
                     StrTran( Left( cParam1, At( ",", cParam1 ) - 1 ), '"', "" )
                  cParam1 := SubStr( cParam1, At( ",", cParam1 ) + 1 )
               ELSE
                  ::aColors[ n ] := ;
                     StrTran( Left( cParam1, At( "}", cParam1 ) - 1 ), '"', "" )
               ENDIF
            NEXT
            ::LoadColors()
         ENDIF
      CASE starts( "NORUNATSTARTUP", cParam )
         ::lRunAtStartup := .F.
      CASE starts( "PATH", cParam )
         ::PathForFiles( AllTrim( cParam1 ) )
      CASE starts( "TAB", cParam )
         ::nTabWidth := Val( Left( cParam1, 3 ) )
      OTHERWISE
         cResult := "Command error"
      ENDCASE

   CASE starts( "OUTPUT", cCommand )
      SetCursor( SC_NONE )
      ::ShowAppScreen()
      SetCursor( SC_NORMAL )

   CASE starts( "PREV", cCommand )
      ::FindPrevious()

   CASE starts( "QUIT", cCommand )
      ::Quit()

   /* TODO: Support RESTART */

   CASE starts( "RESUME", cCommand )
      ::Resume()

   CASE starts( "SPEED", cCommand )
      IF !Empty( cParam )
         ::nSpeed := Val( cParam )
      ELSE
         ::nSpeed := 0
      ENDIF

   CASE starts( "STEP", cCommand )
      ::Step()

   CASE starts( "TP", cCommand )
      ::TracepointAdd( cParam )

   CASE starts( "VIEW", cCommand )
      IF !Empty( cParam ) .AND. starts( "CALLSTACK", Upper( cParam ) )
         ::Stack()
      ELSE
         cResult := "Command error"
      ENDIF

   CASE starts( "WINDOW", cCommand )

      IF ( n := At( " ", cParam ) ) > 0
         cParam1 := AllTrim( SubStr( cParam, n + 1 ) )
         cParam := Left( cParam, n - 1 )
      ENDIF

      DO CASE
      CASE starts( "MOVE", cParam )
         WITH OBJECT ::aWindows[ ::nCurrentWindow ]
            n := At( " ", cParam1 )
            IF n > 0
               n := Val( SubStr( cParam1, n ) )
            ENDIF
            :Resize( Val( cParam1 ), n, ;
                     :nBottom + Val( cParam1 ) - :nTop, :nRight + n - :nLeft )
         ENDWITH
      CASE starts( "NEXT", cParam )
         ::NextWindow()
      CASE starts( "SIZE", cParam )
         WITH OBJECT ::aWindows[ ::nCurrentWindow ]
            n := At( " ", cParam1 )
            IF Val( cParam1 ) >= 2 .AND. n > 0 .AND. Val( SubStr( cParam1, n ) ) > 0
               :Resize( :nTop, :nLeft, Val( cParam1 ) - 1 + :nTop, ;
                        Val( SubStr( cParam1, n ) ) - 1 + :nLeft )
            ENDIF
         ENDWITH
      ENDCASE

   CASE starts( "WP", cCommand )
      ::WatchpointAdd( cParam )

   OTHERWISE
      cResult := "Command error"

   ENDCASE

   IF ::lActive
      DispOutAt( ::oWndCommand:nBottom - 1, ::oWndCommand:nLeft + 1, ;
                 Space( ::oWndCommand:nRight - ::oWndCommand:nLeft - 1 ), ;
                 __DbgColors()[ 2 ] )
      IF !Empty( cResult )
         DispOutAt( ::oWndCommand:nBottom - 1, ::oWndCommand:nLeft + 3, ;
                     cResult, __DbgColors()[ 2 ] )
         ::oWndCommand:ScrollUp( 1 )
      ENDIF
   ENDIF

   RETURN cResult
debugger.prg824
HBDEBUGGER:METHODDoScript( cFileName ) CLASS HBDebugger
METHOD DoScript( cFileName ) CLASS HBDebugger

   LOCAL cInfo
   LOCAL n
   LOCAL cLine
   LOCAL nLen

   IF File( cFileName )
      cInfo := MemoRead( cFileName )
      nLen := MLCount( cInfo, NIL, NIL, .F. )
      FOR n := 1 TO nLen
         cLine := MemoLine( cInfo, 16384, n, NIL, .F., .T. )
         ::DoCommand( cLine )
      NEXT
   ENDIF

   RETURN NIL
debugger.prg1082
HBDEBUGGER:METHODEditColor( nColor, oBrwColors ) CLASS HBDebugger
METHOD EditColor( nColor, oBrwColors ) CLASS HBDebugger

   LOCAL GetList    := {}
   LOCAL lPrevScore := Set( _SET_SCOREBOARD, .F. )
   LOCAL lPrevExit  := Set( _SET_EXIT, .T. )
   LOCAL cColor     := PadR( '"' + ::aColors[ nColor ] + '"',;
                             oBrwColors:getColumn( 2 ):Width )

   oBrwColors:RefreshCurrent()
   oBrwColors:ForceStable()

#ifndef HB_NO_READDBG
   SetCursor( SC_NORMAL )
   @ Row(), Col() + 15 GET cColor COLOR SubStr( ::ClrModal(), 5 ) ;
      VALID iif( Type( cColor ) != "C", ( Alert( "Must be string" ), .F. ), .T. )

   READ
   SetCursor( SC_NONE )
#else
   cColor := getdbginput( Row(), Col() + 15, cColor, ;
                           { | cColor | iif( Type( cColor ) != "C", ;
                                 ( Alert( "Must be string" ), .F. ), .T. ) }, ;
                           SubStr( ::ClrModal(), 5 ) )
#endif

   Set( _SET_SCOREBOARD, lPrevScore )
   Set( _SET_EXIT, lPrevExit )

   IF LastKey() != K_ESC
      ::aColors[ nColor ] := &cColor
   ENDIF

   oBrwColors:RefreshCurrent()
   oBrwColors:ForceStable()

   RETURN NIL
debugger.prg1101
HBDEBUGGER:METHODEditSet( nSet, oBrwSets ) CLASS HBDebugger
METHOD EditSet( nSet, oBrwSets ) CLASS HBDebugger

   LOCAL GetList    := {}
   LOCAL lPrevScore := Set( _SET_SCOREBOARD, .F. )
   LOCAL lPrevExit  := Set( _SET_EXIT, .T. )
   LOCAL cSet       := PadR( __dbgValToStr( Set( nSet ) ), oBrwSets:getColumn( 2 ):Width )
   LOCAL cType      := ValType( Set( nSet ) )

   oBrwSets:RefreshCurrent()
   oBrwSets:ForceStable()

#ifndef HB_NO_READDBG
   SetCursor( SC_NORMAL )
   @ Row(), Col() + 13 GET cSet COLOR SubStr( ::ClrModal(), 5 ) ;
      VALID iif( Type( cSet ) != cType, ( Alert( "Must be of type '" + cType + "'" ), .F. ), .T. )

   READ
   SetCursor( SC_NONE )
#else
   cSet := getdbginput( Row(), Col() + 13, cSet, ;
               { | cSet | iif( Type( cSet ) != cType, ;
                  ( Alert( "Must be of type '" + cType + "'" ), .F. ), .T. ) }, ;
               SubStr( ::ClrModal(), 5 ) )
#endif

   Set( _SET_SCOREBOARD, lPrevScore )
   Set( _SET_EXIT, lPrevExit )

   IF LastKey() != K_ESC
      Set( nSet, &cSet )
   ENDIF

   oBrwSets:RefreshCurrent()
   oBrwSets:ForceStable()

   RETURN NIL
debugger.prg1138
HBDEBUGGER:METHODEditVar( nVar ) CLASS HBDebugger
METHOD EditVar( nVar ) CLASS HBDebugger

   LOCAL cVarName   := ::aVars[ nVar ][ 1 ]
   LOCAL uVarValue  := ::aVars[ nVar ][ 2 ]
   LOCAL cVarType   := ::aVars[ nVar ][ 3 ]
   LOCAL cVarStr
   LOCAL oErr

   uVarValue := ::VarGetValue( ::aVars[ nVar ] )

   IF ValType( uVarValue ) $ "AHOP"
      ::InputBox( cVarName, uVarValue, NIL, .F. )
   ELSE
      cVarStr := ::InputBox( cVarName, __dbgValToStr( uVarValue ),;
                { | u | iif( Type( u ) == "UE", ( Alert( "Expression error" ), .F. ), .T. ) } )
   ENDIF

   IF LastKey() != K_ESC

      DO CASE
      CASE cVarStr == "{ ... }"
         //aArray := ::VarGetValue( ::aVars[ nVar ] )
         IF Len( uVarValue ) > 0
            __DbgArrays( uVarValue, cVarName )
         ELSE
            Alert( "Array is empty" )
         ENDIF

      CASE Upper( Left( cVarStr, 5 ) ) == "CLASS"
         __DbgObject( uVarValue, cVarName )

      OTHERWISE
         BEGIN SEQUENCE WITH {|oErr| break( oErr ) }
            ::VarSetValue( ::aVars[ nVar ], &cVarStr )
         RECOVER USING oErr
            Alert( oErr:description )
         END SEQUENCE
      ENDCASE
   ENDIF

   ::oBrwVars:RefreshCurrent()
   ::oBrwVars:ForceStable()

   RETURN NIL
debugger.prg1176
HBDEBUGGER:METHODFindNext() CLASS HBDebugger
METHOD FindNext() CLASS HBDebugger
   RETURN ::Locate( 1, ::cSearchString )
debugger.prg1222
HBDEBUGGER:METHODFindPrevious() CLASS HBDebugger
METHOD FindPrevious() CLASS HBDebugger
   RETURN ::Locate( 2, ::cSearchString )
debugger.prg1226
HBDEBUGGER:METHODGetExprValue( xExpr, lValid ) CLASS HBDebugger
METHOD GetExprValue( xExpr, lValid ) CLASS HBDebugger

   LOCAL xResult
   LOCAL oErr

   lValid := .F.

   BEGIN SEQUENCE WITH { | oErr | Break( oErr ) }
      xResult := __dbgGetExprValue( ::pInfo, xExpr, @lValid )
      IF !lValid
         xResult := "Syntax error"
      ENDIF
   RECOVER USING oErr
      xResult := oErr:operation + ": " + oErr:description
      IF ISARRAY( oErr:args )
         xResult += "; arguments:"
         AEval( oErr:args, { | x | xResult += " " + AllTrim( hb_CStr( x ) ) } )
      ENDIF
      lValid := .F.
   END SEQUENCE

   RETURN xResult
debugger.prg1230
HBDEBUGGER:METHODGetSourceFiles() CLASS HBDebugger
METHOD GetSourceFiles() CLASS HBDebugger
   RETURN __dbgGetSourceFiles( ::pInfo )
debugger.prg1254
HBDEBUGGER:METHODGlobal() CLASS HBDebugger
METHOD Global() CLASS HBDebugger
   ::lShowGlobals := ! ::lShowGlobals
   ::RefreshVars()
   RETURN NIL
debugger.prg1258
HBDEBUGGER:METHODGo() CLASS HBDebugger
METHOD Go() CLASS HBDebugger
   // we are starting to run again so reset to the deepest call if
   // displaying stack
   IF ! ::oBrwStack == NIL
      ::oBrwStack:GoTop()
   ENDIF
   ::RestoreAppScreen()
   ::RestoreAppState()
   __dbgSetGo( ::pInfo )
   ::Exit()
   RETURN NIL
debugger.prg1264
HBDEBUGGER:METHODGotoLine( nLine ) CLASS HBDebugger
METHOD GotoLine( nLine ) CLASS HBDebugger

   LOCAL nRow
   LOCAL nCol

   /*
   IF ::oBrwVars != NIL
      ::ShowVars()
   ENDIF
   */

   ::oBrwText:GotoLine( nLine )
   nRow := Row()
   nCol := Col()

   // no source code line stored yet

   /*
   IF ::oBrwStack != NIL .AND. Len( ::aCallStack ) > 0 .AND. ;
      ::aCallStack[ ::oBrwStack:Cargo ][ CSTACK_LINE ] == NIL
      ::aCallStack[ ::oBrwStack:Cargo ][ CSTACK_LINE ] := nLine
   ENDIF
   */

   IF ::oWndStack != NIL .AND. ! ::oBrwStack:Stable
      ::oBrwStack:ForceStable()
   ENDIF

   IF ::oWndCode:lFocused .AND. SetCursor() != SC_SPECIAL1
      SetPos( nRow, nCol )
      SetCursor( SC_SPECIAL1 )
   ENDIF
   SetPos( nRow, nCol )

   // Store cursor position to be restored by ::oWndCode:bGotFocus
   ::oWndCode:cargo[ 1 ] := nRow
   ::oWndCode:cargo[ 2 ] := nCol

   RETURN NIL
debugger.prg1277
HBDEBUGGER:METHODHandleEvent() CLASS HBDebugger
METHOD HandleEvent() CLASS HBDebugger

   LOCAL nPopup
   LOCAL oWnd
   LOCAL nKey
   LOCAL nMRow
   LOCAL nMCol
   LOCAL n

   IF ::lAnimate
      IF ::nSpeed != 0
         Inkey( ::nSpeed / 10 )
      ENDIF
      IF __dbgINVOKEDEBUG()  //NextKey() == K_ALT_D
         ::lAnimate := .F.
      ELSE
         ::Step()
         RETURN NIL
      ENDIF
   ENDIF

   ::lEnd := .F.

   DO WHILE ! ::lEnd

      nKey := Inkey( 0, INKEY_ALL )

      DO CASE
      CASE nKey == K_ALT_X
         s_oDebugger:Quit()

      CASE ::oPullDown:IsOpen()
         ::oPullDown:ProcessKey( nKey )
         IF ::oPullDown:nOpenPopup == 0 // Closed
            ::aWindows[ ::nCurrentWindow ]:Show( .T. )
         ENDIF

      CASE nKey == K_LDBLCLK

         IF MRow() != 0 .AND. MRow() != ::nMaxRow

            nMRow := MRow()
            nMCol := MCol()
            FOR n := 1 TO Len( ::aWindows )
               IF ::aWindows[ n ]:IsOver( nMRow, nMCol )
                  IF ! ::aWindows[ n ]:lFocused
                     ::aWindows[ ::nCurrentWindow ]:Show( .F. )
                     ::nCurrentWindow := n
                     ::aWindows[ n ]:Show( .T. )
                  ENDIF
                  ::aWindows[ n ]:LDblClick( nMRow, nMCol )
                  exit
               ENDIF
            NEXT
         ENDIF

      CASE nKey == K_LBUTTONDOWN

         IF MRow() == 0

            IF ( nPopup := ::oPullDown:GetItemOrdByCoors( 0, MCol() ) ) != 0
               IF ! ::oPullDown:IsOpen()
                  IF ::oWndCode:lFocused
                     Eval( ::oWndCode:bLostFocus )
                  ENDIF
                  SetCursor( SC_NONE )
               ENDIF
               ::oPullDown:ShowPopup( nPopup )
            ENDIF

         ELSEIF MRow() != ::nMaxRow

            nMRow := MRow()
            nMCol := MCol()
            FOR n := 1 TO Len( ::aWindows )
               IF ::aWindows[ n ]:IsOver( nMRow, nMCol )
                  IF ! ::aWindows[ n ]:lFocused
                     ::aWindows[ ::nCurrentWindow ]:Show( .F. )
                     ::nCurrentWindow := n
                     ::aWindows[ n ]:Show( .T. )
                  ENDIF
                  ::aWindows[ n ]:LButtonDown( nMRow, nMCol )
                  exit
               ENDIF
            NEXT
         ENDIF

      CASE nKey == K_RBUTTONDOWN
/*
      CASE nKey == K_ESC
         ::RestoreAppStatus()
         s_oDebugger := NIL
         s_lExit := .T.
         DispEnd()
         ::Exit()
*/

      CASE nKey == K_UP .OR. nKey == K_DOWN .OR. nKey == K_HOME .OR. ;
           nKey == K_END .OR. nKey == K_ENTER .OR. nKey == K_PGDN .OR. ;
           nKey == K_PGUP .OR. nKey == K_DEL .OR. nKey == K_LEFT .OR. ;
           nKey == K_RIGHT .OR. nKey == K_CTRL_ENTER

         oWnd := ::aWindows[ ::nCurrentWindow ]
         oWnd:KeyPressed( nKey )

      CASE nKey == K_F1
         ::ShowHelp()

      CASE nKey == K_F4
         ::ShowAppScreen()

      CASE nKey == K_F5
         ::Go()

      CASE nKey == K_CTRL_F5
         ::NextRoutine()

      CASE nKey == K_F6
         ::ShowWorkAreas()

      CASE nKey == K_F7
         ::ToCursor()

      CASE nKey == K_F8
         ::Step()

      CASE nKey == K_F9
         ::ToggleBreakPoint()

      CASE nKey == K_F10
         ::Trace()

      CASE nKey == K_TAB
         ::NextWindow()

      CASE nKey == K_SH_TAB
         ::PrevWindow()

      CASE ::oWndCommand:lFocused .AND. nKey < 272 // Alt
         ::oWndCommand:KeyPressed( nKey )

      OTHERWISE
         IF ( nPopup := ::oPullDown:GetHotKeyPos( __dbgAltToKey( nKey ) ) ) != 0
            IF ::oPullDown:nOpenPopup != nPopup
               IF ::oWndCode:lFocused
                  Eval( ::oWndCode:bLostFocus )
               ENDIF
               SetCursor( SC_NONE )
               ::oPullDown:ShowPopup( nPopup )
            ENDIF
         ENDIF
      ENDCASE
   ENDDO

   RETURN NIL
debugger.prg1318
HBDEBUGGER:METHODHide() CLASS HBDebugger
METHOD Hide() CLASS HBDebugger
   ::CloseDebuggerWindow()
   RETURN NIL
debugger.prg1474
HBDEBUGGER:METHODHideCallStack() CLASS HBDebugger
METHOD HideCallStack() CLASS HBDebugger

   ::lShowCallStack := .F.

   IF ::oWndStack != NIL
      DispBegin()
      ::oWndStack:Hide()
      IF ::aWindows[ ::nCurrentWindow ] == ::oWndStack
        ::NextWindow()
      ENDIF
      ::RemoveWindow( ::oWndStack )
      ::oWndStack := NIL

      ::oWndCode:Resize(,,, ::oWndCode:nRight + 16 )
      IF ::oWndVars != NIL
         ::oWndVars:Resize(,,, ::oWndVars:nRight + 16 )
      ENDIF
      IF ::oWndPnt != NIL
         ::oWndPnt:Resize(,,, ::oWndPnt:nRight + 16 )
      ENDIF
      DispEnd()
   ENDIF

   RETURN NIL
debugger.prg1479
HBDEBUGGER:METHODHideVars() CLASS HBDebugger
METHOD HideVars() CLASS HBDebugger
   LOCAL nTop

   IF ::oWndVars == NIL
      RETURN NIL
   ENDIF

   ::oWndVars:Hide()
   IF ::oWndPnt == NIL
      nTop := 1
   ELSE
      ::oWndPnt:Resize( 1, , ::oWndPnt:nBottom - ( ::oWndPnt:nTop - 1 ) )
      ::oBrwPnt:Resize( 2, , ::oWndPnt:nBottom - 1 )
      nTop := ::oWndPnt:nBottom + 1
   ENDIF
   ::oWndCode:Resize( nTop )
   ::oBrwText:Resize( ::oWndCode:nTop + 1 )
   IF ::oWndCode:lFocused
      ::oWndCode:cargo[ 1 ] := Row()
      ::oWndCode:cargo[ 2 ] := Col()
   ENDIF

   IF ::aWindows[ ::nCurrentWindow ] == ::oWndVars
      ::NextWindow()
   ENDIF

   RETURN NIL
debugger.prg1505
HBDEBUGGER:METHODInputBox( cMsg, uValue, bValid, lEditable ) CLASS HBDebugger
METHOD InputBox( cMsg, uValue, bValid, lEditable ) CLASS HBDebugger

   LOCAL nTop    := Int( ( ::nMaxRow / 2 ) - 5 )
   LOCAL nLeft   := Int( ( ::nMaxCol / 2 ) - 25 )
   LOCAL nBottom := nTop + 2
   LOCAL nRight  := nLeft + 50
   LOCAL cType   := ValType( uValue )
   LOCAL nWidth  := nRight - nLeft - 1
   LOCAL cPicture
   LOCAL uTemp
   LOCAL nOldCursor
   LOCAL lScoreBoard := Set( _SET_SCOREBOARD, .F. )
   LOCAL lExit
   LOCAL oWndInput := HBDbWindow():New( nTop, nLeft, nBottom, nRight, cMsg,;
                                       ::oPullDown:cClrPopup )
#ifndef HB_NO_READDBG
   LOCAL GetList := {}
   LOCAL bMouseSave
   LOCAL oGet
#endif

   DEFAULT lEditable TO .T.

   IF cType == "C" .AND. Len( uValue ) > nWidth
      uTemp := uValue
      cPicture := "@s" + LTrim( Str( nWidth ) )
   ELSE
      uTemp := PadR( uValue, nWidth )
   ENDIF

   oWndInput:lShadow := .T.
   oWndInput:Show()

   IF lEditable
#ifndef HB_NO_READDBG
      IF bValid == NIL
         @ nTop + 1, nLeft + 1 GET uTemp PICTURE cPicture COLOR "," + __DbgColors()[ 5 ]
      ELSE
         @ nTop + 1, nLeft + 1 GET uTemp PICTURE cPicture VALID Eval( bValid, uTemp ) ;
           COLOR "," + __DbgColors()[ 5 ]
      ENDIF

      nOldCursor := SetCursor( SC_NORMAL )
      oGet := ATail( GetList )
      bMouseSave := SetKey( K_LBUTTONDOWN, { || iif( MRow() == nTop .AND. MCol() == nLeft + 2,;
         ( oGet:undo(), oGet:exitState := GE_ESCAPE, .T. ), .F. ) } )
      READ
      SetKey( K_LBUTTONDOWN, bMouseSave)
      SetCursor( nOldCursor )
#else
      uTemp := getdbginput( nTop + 1, nLeft + 1, uTemp, bValid, __DbgColors()[ 5 ] )
#endif
   ELSE
      DispOutAt( nTop + 1, nLeft + 1, __dbgValToStr( uValue ), "," + __DbgColors()[ 5 ] )
      SetPos( nTop + 1, nLeft + 1 )
      nOldCursor := SetCursor( SC_NONE )

      lExit := .F.

      DO WHILE ! lExit
         Inkey( 0 )

         DO CASE
         CASE LastKey() == K_ESC
            lExit := .T.

         CASE LastKey() == K_ENTER
            IF cType == "A"
               IF Len( uValue ) == 0
                  Alert( "Array is empty" )
               ELSE
                  __DbgArrays( uValue, cMsg )
               ENDIF

            ELSEIF cType == "H"
               IF Len( uValue ) == 0
                  Alert( "Hash is empty" )
               ELSE
                  __DbgHashes( uValue, cMsg )
               ENDIF

            ELSEIF cType == "O"
               __DbgObject( uValue, cMsg )

            ELSE
               Alert( "Value cannot be edited" )
            ENDIF

         OTHERWISE
            Alert( "Value cannot be edited" )
         ENDCASE
      ENDDO

      SetCursor( nOldCursor )
   ENDIF

#ifndef HB_NO_READDBG
   nOldCursor := SetCursor( SC_NORMAL )
   READ
   SetCursor( nOldCursor )
#endif

   oWndInput:Hide()
   Set( _SET_SCOREBOARD, lScoreBoard )

   DO CASE
   CASE cType == "C" ; uTemp := AllTrim( uTemp )
   CASE cType == "D" ; uTemp := CToD( uTemp )
   CASE cType == "N" ; uTemp := Val( uTemp )
   ENDCASE

   RETURN iif( LastKey() != K_ESC, uTemp, uValue )
debugger.prg1534
HBDEBUGGER:METHODInspect( uValue, cValueName ) CLASS HBDebugger
METHOD Inspect( uValue, cValueName ) CLASS HBDebugger

   uValue := ::InputBox( uValue, cValueName,, .F. )

   RETURN NIL
debugger.prg1648
HBDEBUGGER:METHODIsValidStopLine( cName, nLine ) CLASS HBDebugger
METHOD IsValidStopLine( cName, nLine ) CLASS HBDebugger
   RETURN __dbgIsValidStopLine( ::pInfo, cName, nLine )
debugger.prg1655
HBDEBUGGER:METHODLineNumbers( lLineNumbers ) CLASS HBDebugger
METHOD LineNumbers( lLineNumbers ) CLASS HBDebugger

   DEFAULT lLineNumbers TO !::lLineNumbers

   ::lLineNumbers := lLineNumbers
   ::oPulldown:GetItemByIdent( "LINE" ):checked := ::lLineNumbers
   IF ::oBrwText != NIL
      ::oBrwText:lLineNumbers := lLineNumbers
      ::oBrwText:RefreshAll()
   ENDIF

   RETURN Self
debugger.prg1659
HBDEBUGGER:METHODListBox( cCaption, aItems ) CLASS HBDebugger
METHOD ListBox( cCaption, aItems ) CLASS HBDebugger

   LOCAL nItems
   LOCAL nMaxWid
   LOCAL nLeft
   LOCAL nTop
   LOCAL nBottom
   LOCAL nRight
   LOCAL oWndList
   LOCAL cSelected := ""
   LOCAL cColors
   LOCAL n

   nItems := Len( aItems )
   nMaxWid := Len( cCaption ) + 2
   AEval( aItems, { | x | nMaxWid := Max( Len( x ), nMaxWid ) } )
   nMaxWid += 2

   nTop    := ( ::nMaxRow / 2 ) - Min( nItems, ::nMaxRow - 5 ) / 2
   nBottom := ( ::nMaxRow / 2 ) + Min( nItems, ::nMaxRow - 5 ) / 2 + 1
   nLeft   := ( ::nMaxCol / 2 ) - Min( nMaxWid, ::nMaxCol * 3 / 2 ) / 2
   nRight  := ( ::nMaxCol / 2 ) + Min( nMaxWid, ::nMaxCol * 3 / 2 ) / 2
   oWndList := HBDbWindow():new( nTop, nLeft, nBottom, nRight, cCaption, ;
                                ::oPullDown:cClrPopup )
   oWndList:lShadow := .T.
   oWndList:Show()

   cColors := SetColor( ::aColors[ 8 ] + "," + ::aColors[ 10 ] )
   n := AChoice( nTop + 1, nLeft + 1, nBottom - 1, nRight - 1, aItems )
   SetColor( cColors )

   oWndList:Hide()
   RETURN n
debugger.prg1673
HBDEBUGGER:METHODLoadCallStack() CLASS HBDebugger
METHOD LoadCallStack() CLASS HBDebugger

   LOCAL i
   LOCAL nDebugLevel
   LOCAL nCurrLevel
   LOCAL nlevel
   LOCAL nPos

   ::aProcStack := Array( ::nProcLevel )

   nCurrLevel := __dbgProcLevel() - 1
   nDebugLevel := nCurrLevel - ::nProcLevel + 1

   FOR i := nDebugLevel TO nCurrLevel
      nLevel := nCurrLevel - i + 1
      nPos := AScan( ::aCallStack, { | a | a[ CSTACK_LEVEL ] == nLevel } )
      IF nPos > 0
         // a procedure with debug info
         ::aProcStack[ i - nDebugLevel + 1 ] := ::aCallStack[ nPos ]
      ELSE
         ::aProcStack[ i - nDebugLevel + 1 ] := { , ProcName( i ) + "(" + LTrim( Str( ProcLine( i ) ) ) + ")", , nLevel, , }
      ENDIF
   NEXT

   RETURN NIL
debugger.prg1708
HBDEBUGGER:METHODLoadColors() CLASS HBDebugger
METHOD LoadColors() CLASS HBDebugger

   LOCAL n

   ::oPullDown:LoadColors()
   IF ::lActive
      ::oPullDown:Refresh()
      ::BarDisplay()
   ENDIF
   FOR n := 1 TO Len( ::aWindows )
      ::aWindows[ n ]:LoadColors()
      IF ::lActive
         ::aWindows[ n ]:Refresh()
      ENDIF
   NEXT

   RETURN NIL
debugger.prg1735
HBDEBUGGER:METHODLoadSettings() CLASS HBDebugger
METHOD LoadSettings() CLASS HBDebugger
   ::DoScript( ::cSettingsFileName )
   RETURN NIL
debugger.prg1754
HBDEBUGGER:METHODLoadVars() CLASS HBDebugger
METHOD LoadVars() CLASS HBDebugger // updates monitored variables

   LOCAL nCount
   LOCAL n
   LOCAL m
   LOCAL xValue
   LOCAL cName
   LOCAL aVars
   LOCAL aBVars

   aBVars := {}

   IF ::lShowPublics
      nCount := __mvDbgInfo( HB_MV_PUBLIC )
      FOR n := nCount TO 1 STEP -1
         xValue := __mvDbgInfo( HB_MV_PUBLIC, n, @cName )
         AAdd( aBVars, { cName, xValue, "Public" } )
      NEXT
   ENDIF

   IF ::lShowPrivates
      nCount := __mvDbgInfo( HB_MV_PRIVATE )
      FOR n := nCount TO 1 STEP -1
         xValue := __mvDbgInfo( HB_MV_PRIVATE, n, @cName )
         AAdd( aBVars, { cName, xValue, "Private" } )
      NEXT
   ENDIF

   IF ::aProcStack[ ::oBrwStack:Cargo ][ CSTACK_LINE ] != NIL
      IF ::lShowGlobals
         cName := ::aProcStack[ ::oBrwStack:Cargo ][ CSTACK_MODULE ]
         FOR n := 1 TO Len( ::aModules )
            IF !::lShowAllGlobals
               IF !hb_FileMatch( ::aModules[ n ][ MODULE_NAME ], cName )
                  LOOP
               ENDIF
            ENDIF
            aVars := ::aModules[ n ][ MODULE_GLOBALS ]
            FOR m := 1 TO Len( aVars )
               AAdd( aBVars, aVars[ m ] )
            NEXT
            IF !::lShowAllGlobals
               aVars := ::aModules[ n ][ MODULE_EXTERNGLOBALS ]
               FOR m := 1 TO Len( aVars )
                  AAdd( aBVars, aVars[ m ] )
               NEXT
            ENDIF
         NEXT
      ENDIF

      IF ::lShowStatics
         cName := ::aProcStack[ ::oBrwStack:Cargo ][ CSTACK_MODULE ]
         n := AScan( ::aModules, { | a | hb_FileMatch( a[ MODULE_NAME ], cName ) } )
         IF n > 0
            aVars := ::aModules[ n ][ MODULE_STATICS ]
            FOR m := 1 TO Len( aVars )
               AAdd( aBVars, aVars[ m ] )
            NEXT
         ENDIF
         aVars := ::aProcStack[ ::oBrwStack:Cargo ][ CSTACK_STATICS ]
         FOR n := 1 TO Len( aVars )
            AAdd( aBVars, aVars[ n ] )
         NEXT
      ENDIF

      IF ::lShowLocals
         aVars := ::aProcStack[ ::oBrwStack:Cargo ][ CSTACK_LOCALS ]
         FOR n := 1 TO Len( aVars )
            cName := aVars[ n ][ VAR_NAME ]
            m := AScan( aBVars,; // Is there another var with this name ?
                        { | aVar | aVar[ VAR_NAME ] == cName .AND. Left( aVar[ VAR_TYPE ], 1 ) == "S" } )
            IF m > 0
               aBVars[ m ] := aVars[ n ]
            ELSE
               AAdd( aBVars, aVars[ n ] )
            ENDIF
         NEXT
      ENDIF
   ENDIF

   IF ::oBrwVars != NIL .AND. ::oBrwVars:cargo[ 1 ] > Len( aBVars )
      ::oBrwVars:GoTop()
   ENDIF
   ::aVars := aBVars
   IF ::lSortVars
      ::Sort()
   ENDIF

   RETURN NIL
debugger.prg1759
HBDEBUGGER:METHODLocal() CLASS HBDebugger
METHOD Local() CLASS HBDebugger
   ::lShowLocals := ! ::lShowLocals
   ::RefreshVars()
   RETURN NIL
debugger.prg1850
HBDEBUGGER:METHODLocate( nMode, cValue ) CLASS HBDebugger
METHOD Locate( nMode, cValue ) CLASS HBDebugger

   LOCAL lFound

   DEFAULT nMode TO 0

   IF Empty( cValue )
      ::cSearchString := PadR( ::cSearchString, 256 )
      cValue := ::InputBox( "Search string", ::cSearchString )
      IF Empty( cValue )
         RETURN NIL
      ENDIF
   ENDIF

   ::cSearchString := cValue

   lFound := ::oBrwText:Search( ::cSearchString, ::lCaseSensitive, nMode )

   // Save cursor position to be restored by ::oWndCode:bGotFocus
   ::oWndCode:cargo[ 1 ] := Row()
   ::oWndCode:cargo[ 2 ] := Col()
   RETURN lFound
debugger.prg1856
HBDEBUGGER:METHODLocatePrgPath( cPrgName ) CLASS HBDebugger
METHOD LocatePrgPath( cPrgName ) CLASS HBDebugger

   LOCAL aPaths := ::aPathDirs
   LOCAL iMax := Len( aPaths )
   LOCAL cSep := hb_OSPathSeparator()
   LOCAL cRetPrgName
   LOCAL i

   FOR i := 1 TO iMax
      cRetPrgName := aPaths[ i ] + cSep + cPrgName
      IF File( cRetPrgName )
         RETURN cRetPrgName
      ENDIF
   NEXT

   RETURN NIL
debugger.prg1880
HBDEBUGGER:METHODMonoDisplay() CLASS HBDebugger
METHOD MonoDisplay() CLASS HBDebugger

   ::lMonoDisplay := ! ::lMonoDisplay
   ::oPullDown:GetItemByIdent( "MONO" ):checked := ::lMonoDisplay
   ::LoadColors()

   RETURN NIL
debugger.prg1898
HBDEBUGGER:METHODNextRoutine() CLASS HBDebugger
METHOD NextRoutine() CLASS HBDebugger
   ::RestoreAppScreen()
   ::RestoreAppState()
   __dbgSetNextRoutine( ::pInfo )
   ::Exit()
   RETURN Self
debugger.prg1907
HBDEBUGGER:METHODNextWindow() CLASS HBDebugger
METHOD NextWindow() CLASS HBDebugger

   LOCAL oWnd

   IF Len( ::aWindows ) > 0
      oWnd := ::aWindows[ ::nCurrentWindow++ ]
      oWnd:Show( .F. )
      IF ::nCurrentWindow > Len( ::aWindows )
         ::nCurrentWindow := 1
      ENDIF
      DO WHILE ! ::aWindows[ ::nCurrentWindow ]:lVisible
         ::nCurrentWindow++
         IF ::nCurrentWindow > Len( ::aWindows )
            ::nCurrentWindow := 1
         ENDIF
      ENDDO
      oWnd := ::aWindows[ ::nCurrentWindow ]
      oWnd:Show( .T. )
   ENDIF

   RETURN NIL
debugger.prg1915
HBDEBUGGER:METHODOpen() CLASS HBDebugger
METHOD Open() CLASS HBDebugger

   LOCAL nFileName
   LOCAL cFileName
   LOCAL cRealName
   LOCAL aFiles := ::GetSourceFiles()
   LOCAL cExt

   ASort( aFiles )
   ASize( aFiles, Len( aFiles ) + 1 )
   AIns( aFiles, 1, "(Another file)" )

   nFileName := ::ListBox( "Please choose a source file", aFiles )
   IF nFileName == 0
      RETURN NIL
   ELSEIF nFileName == 1
      cFileName := ::InputBox( "Please enter the filename", Space( 255 ) )
      cFileName := AllTrim( cFileName )
   ELSE
      cFileName := aFiles[ nFileName ]
   ENDIF

   IF !Empty( cFileName ) ;
        .AND. ( ValType( ::cPrgName ) == "U" .OR. !hb_FileMatch( cFileName, ::cPrgName ) )

      IF ! File( cFileName ) .AND. ! Empty( ::cPathForFiles )
         cRealName := ::LocatePrgPath( cFileName )
         IF Empty( cRealName )
           Alert( "File '" + cFileName + "' not found!" )
           RETURN NIL
         ENDIF
         cFileName := cRealName
      ENDIF
      ::cPrgName := cFileName
      hb_FNameSplit( cFileName, NIL, NIL, @cExt )
      ::lPPO := ( Lower( cExt ) == ".ppo" )
      ::oPulldown:GetItemByIdent( "PPO" ):Checked := ::lPPO
      ::oBrwText := HBBrwText():New( ::oWndCode:nTop + 1, ::oWndCode:nLeft + 1,;
                    ::oWndCode:nBottom - 1, ::oWndCode:nRight - 1, cFileName,;
                    __DbgColors()[ 2 ] + "," + __DbgColors()[ 5 ] + "," + ;
                    __DbgColors()[ 3 ] + "," + __DbgColors()[ 6 ], ;
                    ::lLineNumbers, ::nTabWidth )
      ::oWndCode:Browser := ::oBrwText
      ::RedisplayBreakpoints()               // check for breakpoints in this file and display them
      ::oWndCode:SetCaption( ::cPrgName )
      ::oWndCode:Refresh()       // to force the window caption to update
   ENDIF
   RETURN NIL
debugger.prg1938
HBDEBUGGER:METHODOpenPPO() CLASS HBDebugger
METHOD OpenPPO() CLASS HBDebugger

   LOCAL lSuccess := .F.
   LOCAL cDir
   LOCAL cName
   LOCAL cExt

   IF Empty( ::cPrgName )
      RETURN .F.
   ENDIF

   hb_FNameSplit( ::cPrgName, @cDir, @cName, @cExt )

   IF Lower( cExt ) == ".ppo"
      ::cPrgName := hb_FNameMerge( cDir, cName, ".prg" )
      lSuccess := File( ::cPrgName )
      ::lPPO := !lSuccess
   ELSE
      ::cPrgName := hb_FNameMerge( cDir, cName, ".ppo" )
      lSuccess := File( ::cPrgName )
      ::lPPO := lSuccess
   ENDIF

   IF lSuccess
      ::oBrwText := HBBrwText():New( ::oWndCode:nTop + 1, ::oWndCode:nLeft + 1,;
        ::oWndCode:nBottom - 1, ::oWndCode:nRight - 1, ::cPrgName,;
        __DbgColors()[ 2 ] + "," + __DbgColors()[ 5 ] + "," + ;
        __DbgColors()[ 3 ] + "," + __DbgColors()[ 6 ], ::lLineNumbers, ::nTabWidth )
      ::oWndCode:Browser := ::oBrwText
      ::RedisplayBreakpoints()               // check for breakpoints in this file and display them
      ::oWndCode:SetCaption( ::cPrgName )
      ::oWndCode:Refresh() // to force the window caption to update
   ENDIF

   ::oPullDown:GetItemByIdent( "PPO" ):checked := ::lPPO

   RETURN lSuccess
debugger.prg1988
HBDEBUGGER:METHODOSShell() CLASS HBDebugger
METHOD OSShell() CLASS HBDebugger

   LOCAL cImage := SaveScreen()
   LOCAL cColors := SetColor()
   LOCAL cOs := Upper( OS() )
   LOCAL cShell
   LOCAL oE

   SetColor( "W/N" )
   CLS
   ? "Type 'exit' to RETURN to the Debugger"
   SetCursor( SC_NORMAL )

   BEGIN SEQUENCE WITH { | objErr | Break( objErr ) }

      IF At( "WINDOWS", cOs ) != 0 .OR. At( "DOS", cOs ) != 0 .OR. At( "OS/2", cOs ) != 0
         cShell := GetEnv( "COMSPEC" )
         RUN ( cShell )
      ELSEIF At( "LINUX", cOs ) != 0 .OR. At( "BSD", cOs ) != 0 .OR. At( "DARWIN", cOs ) != 0
         cShell := GetEnv( "SHELL" )
         RUN ( cShell )
      ELSE
         Alert( "Not implemented yet!" )
      ENDIF

   RECOVER USING oE

      Alert( "Error: " + oE:description )

   END SEQUENCE

   SetCursor( SC_NONE )
   RestScreen( ,,,, cImage )
   SetColor( cColors )

   RETURN NIL
debugger.prg2027
HBDEBUGGER:METHODQuit() CLASS HBDebugger
METHOD Quit() CLASS HBDebugger

   ::Exit()
   ::Hide()
   __dbgSetQuit( ::pInfo )
   s_oDebugger := NIL

   __QUIT()

   RETURN NIL
debugger.prg2065
HBDEBUGGER:METHODPathForFiles( cPathForFiles ) CLASS HBDebugger
METHOD PathForFiles( cPathForFiles ) CLASS HBDebugger

   IF cPathForFiles == NIL
      cPathForFiles := ::InputBox( "Search path for source files:", ::cPathForFiles )
   ENDIF
   ::cPathForFiles := cPathForFiles
   ::aPathDirs := PathToArray( ::cPathForFiles )

   ::Resume()
   RETURN Self
debugger.prg2077
HBDEBUGGER:METHODPrevWindow() CLASS HBDebugger
METHOD PrevWindow() CLASS HBDebugger

   LOCAL oWnd

   IF Len( ::aWindows ) > 0

      oWnd := ::aWindows[ ::nCurrentWindow-- ]
      oWnd:Show( .F. )
      IF ::nCurrentWindow < 1
         ::nCurrentWindow := Len( ::aWindows )
      ENDIF
      DO WHILE ! ::aWindows[ ::nCurrentWindow ]:lVisible
         ::nCurrentWindow--
         IF ::nCurrentWindow < 1
            ::nCurrentWindow := Len( ::aWindows )
         ENDIF
      ENDDO
      oWnd := ::aWindows[ ::nCurrentWindow ]
      oWnd:Show( .T. )

   ENDIF

   RETURN NIL
debugger.prg2089
HBDEBUGGER:METHODPrivate() CLASS HBDebugger
METHOD Private() CLASS HBDebugger

   ::lShowPrivates := ! ::lShowPrivates
   ::RefreshVars()

   RETURN NIL
debugger.prg2114
HBDEBUGGER:METHODPublic() CLASS HBDebugger
METHOD Public() CLASS HBDebugger

   ::lShowPublics := ! ::lShowPublics
   ::RefreshVars()

   RETURN NIL
debugger.prg2122
HBDEBUGGER:METHODRedisplayBreakPoints() CLASS HBDebugger
METHOD RedisplayBreakPoints() CLASS HBDebugger

   LOCAL n

   FOR n := 1 TO Len( ::aBreakpoints )
      IF hb_FileMatch( ::aBreakpoints[ n ][ 2 ], strip_path( ::cPrgName ) )
         ::oBrwText:ToggleBreakPoint( ::aBreakpoints[ n ][ 1 ], .T.)
      ENDIF
   NEXT

   RETURN NIL
debugger.prg2131
HBDEBUGGER:METHODRefreshVars() CLASS HBDebugger
METHOD RefreshVars() CLASS HBDebugger

   ::oPulldown:GetItemByIdent( "GLOBAL" ):checked := ::lShowGlobals
   ::oPulldown:GetItemByIdent( "LOCAL" ):checked := ::lShowLocals
   ::oPulldown:GetItemByIdent( "PRIVATE" ):checked := ::lShowPrivates
   ::oPulldown:GetItemByIdent( "PUBLIC" ):checked := ::lShowPublics
   ::oPulldown:GetItemByIdent( "STATIC" ):checked := ::lShowStatics
   ::oPulldown:GetItemByIdent( "ALL" ):checked := ::lAll
   ::oPulldown:GetItemByIdent( "SHOWALLGLOBALS" ):checked := ::lShowAllGlobals

   IF ::lActive
      IF ::lShowGlobals .OR. ::lShowPublics .OR. ::lShowPrivates .OR. ::lShowStatics .OR. ::lShowLocals
         ::LoadVars()
         ::ShowVars()
      ELSE
         ::HideVars()
      ENDIF
   ENDIF

   RETURN NIL
debugger.prg2144
HBDEBUGGER:METHODRemoveWindow( oWnd ) CLASS HBDebugger
METHOD RemoveWindow( oWnd ) CLASS HBDebugger

   LOCAL n := AScan( ::aWindows, { | o | o == oWnd } )

   IF n != 0
      ::aWindows := ADel( ::aWindows, n )
      ::aWindows := ASize( ::aWindows, Len( ::aWindows ) - 1 )
   ENDIF

   ::nCurrentWindow := 1

   RETURN NIL
debugger.prg2166
HBDEBUGGER:METHODResizeWindows( oWindow ) CLASS HBDebugger
METHOD ResizeWindows( oWindow ) CLASS HBDebugger

   LOCAL oWindow2
   LOCAL nTop
   LOCAL lVisible2 := .F.

   IF oWindow == ::oWndVars
      oWindow2 := ::oWndPnt
   ELSEIF oWindow == ::oWndPnt
      oWindow2 := ::oWndVars
   ENDIF

   DispBegin()
   IF oWindow2 == NIL
      nTop := oWindow:nBottom + 1
   ELSE
      lVisible2 := oWindow2:lVisible
      IF oWindow2:lVisible
         IF oWindow:nTop < oWindow2:nTop
            nTop := oWindow2:nBottom - oWindow2:nTop + 1
            oWindow2:Resize( oWindow:nBottom + 1,, oWindow:nBottom + nTop )
         ELSE
            nTop := oWindow:nBottom - oWindow:nTop + 1
            oWindow:Resize( oWindow2:nBottom + 1,, oWindow2:nBottom + nTop )
         ENDIF
         nTop := Max( oWindow:nBottom, oWindow2:nBottom ) + 1
      ELSE
         IF oWindow:nTop > 1
            nTop := oWindow:nBottom - oWindow:nTop + 1
            oWindow:Resize( 1, NIL, nTop )
         ENDIF
         nTop := oWindow:nBottom + 1
      ENDIF
   ENDIF

   oWindow:hide()
   IF oWindow2 != NIL
      oWindow2:hide()
   ENDIF

   ::oWndCode:Resize( nTop )
   IF ::oWndCode:lFocused
      ::oWndCode:cargo[ 1 ] := Row()
      ::oWndCode:cargo[ 2 ] := Col()
   ENDIF

   IF oWindow2 != NIL .AND. lVisible2
      oWindow2:show()
   ENDIF
   oWindow:show()
   DispEnd()

   RETURN Self
debugger.prg2180
HBDEBUGGER:METHODRestoreAppScreen() CLASS HBDebugger
METHOD RestoreAppScreen() CLASS HBDebugger

   LOCAL i

   ::CloseDebuggerWindow()

   FOR i := 1 TO ::nAppDispCount
      DispBegin()
   NEXT

   RETURN NIL
debugger.prg2235
HBDEBUGGER:METHODRestoreAppState() CLASS HBDebugger
METHOD RestoreAppState() CLASS HBDebugger
   Set( _SET_DIRCASE, ::nAppDirCase )
   Set( _SET_FILECASE, ::nAppFileCase )
   Set( _SET_TYPEAHEAD, ::nAppTypeAhead )
   hb_SetLastKey( ::nAppLastKey )
#ifdef __XHARBOUR__
   SetInkeyAfterBlock( ::bAppInkeyAfter )
   SetInkeyBeforeBlock( ::bAppInkeyBefore )
   __SetClassScope( ::bAppClassScope )
#endif
   __GetListSetActive( ::oAppGetList )
   RETURN NIL
debugger.prg2248
HBDEBUGGER:METHODRestoreSettings() CLASS HBDebugger
METHOD RestoreSettings() CLASS HBDebugger

   ::cSettingsFileName := ::InputBox( "File name", ::cSettingsFileName )

   IF LastKey() != K_ESC
      ::LoadSettings()
      ::ShowVars()
   ENDIF

   RETURN NIL
debugger.prg2262
HBDEBUGGER:METHODSaveAppScreen() CLASS HBDebugger
METHOD SaveAppScreen() CLASS HBDebugger

   LOCAL nRight
   LOCAL nTop
   LOCAL i
  
   ::nAppDispCount := DispCount()
   FOR i := 1 TO ::nAppDispCount
      DispEnd()
   NEXT
  
   ::OpenDebuggerWindow()
  
   IF ::nMaxRow != MaxRow() .OR. ::nMaxCol != MaxCol()
      DispBegin()
      ::nMaxRow := MaxRow()
      ::nMaxCol := MaxCol()
      nTop := 1
      nRight := ::nMaxCol
      ::oWndCommand:Resize( ::nMaxRow - 5, 0, ::nMaxRow - 1, ::nMaxCol )
      ::oGetListCommand:Get():Row := ::oWndCommand:nBottom - 1
      ::oGetListCommand:Get():Col := ::oWndCommand:nLeft + 3
      ::oBrwStack:nTop := 2
      ::oBrwStack:nLeft := ::nMaxCol - 14
      ::oBrwStack:nRight := ::nMaxCol - 1
      ::oBrwStack:nBottom := ::nMaxRow - 7
      IF ::oWndStack != NIL
         nRight -= 16
         ::oWndStack:Resize( , nRight + 1, ::nMaxRow - 6, ::nMaxCol )
      ENDIF
      IF ::oWndVars != NIL
         ::oWndVars:Resize( , , , nRight )
         nTop := Max( nTop, ::oWndVars:nBottom + 1 )
      ENDIF
      IF ::oWndPnt != NIL
         ::oWndPnt:Resize( , , , nRight )
         nTop := Max( nTop, ::oWndPnt:nBottom + 1 )
      ENDIF
      ::oWndCode:Resize( nTop, 0, ::nMaxRow - 6, nRight )
      ::oPullDown:Refresh()
      ::BarDisplay()
      DispEnd()
   ENDIF
   RETURN NIL
debugger.prg2274
HBDEBUGGER:METHODSaveAppState() CLASS HBDebugger
METHOD SaveAppState() CLASS HBDebugger
   ::nAppDirCase := Set( _SET_DIRCASE, 0 )
   ::nAppFileCase := Set( _SET_FILECASE, 0 )
   ::nAppTypeAhead := Set( _SET_TYPEAHEAD, 16 )
   ::nAppLastKey := LastKey()
#ifdef __XHARBOUR__
   ::bAppInkeyAfter := SetInkeyAfterBlock( NIL )
   ::bAppInkeyBefore := SetInkeyBeforeBlock( NIL )
   ::bAppClassScope := __SetClassScope( .F. )
#endif
   ::oAppGetList := __GetListActive()
   RETURN NIL
debugger.prg2320
HBDEBUGGER:METHODSaveSettings() CLASS HBDebugger
METHOD SaveSettings() CLASS HBDebugger

   LOCAL cInfo := ""
   LOCAL n
   LOCAL oWnd

   ::cSettingsFileName := ::InputBox( "File name", ::cSettingsFileName )

   IF LastKey() != K_ESC

      IF ! Empty( ::cPathForFiles )
         cInfo += "Options Path " + ::cPathForFiles + hb_OSNewLine()
      ENDIF

      cInfo += "Options Colors {"
      FOR n := 1 TO Len( ::aColors )
         cInfo += '"' + ::aColors[ n ] + '"'
         IF n < Len( ::aColors )
            cInfo += ","
         ENDIF
      NEXT
      cInfo += "}" + hb_OSNewLine()

      IF ::lMonoDisplay
         cInfo += "Options mono " + hb_OSNewLine()
      ENDIF

      IF !::lRunAtStartup
         cInfo += "Options NoRunAtStartup " + hb_OSNewLine()
      ENDIF

      IF ::nSpeed != 0
         cInfo += "Run Speed " + LTrim( Str( ::nSpeed ) ) + hb_OSNewLine()
      ENDIF

      IF ::nTabWidth != 4
         cInfo += "Options Tab " + LTrim( Str( ::nTabWidth ) ) + hb_OSNewLine()
      ENDIF

      IF ::lShowStatics
         cInfo += "Monitor Static" + hb_OSNewLine()
      ENDIF

      IF ::lShowPublics
         cInfo += "Monitor Public" + hb_OSNewLine()
      ENDIF

      IF ::lShowLocals
         cInfo += "Monitor Local" + hb_OSNewLine()
      ENDIF

      IF ::lShowPrivates
         cInfo += "Monitor Private" + hb_OSNewLine()
      ENDIF

      IF ::lShowGlobals
         cInfo += "Monitor Global" + hb_OSNewLine()
      ENDIF

      IF ::lSortVars
         cInfo += "Monitor Sort" + hb_OSNewLine()
      ENDIF

      IF ::lShowCallStack
         cInfo += "View CallStack" + hb_OSNewLine()
      ENDIF

      IF ! ::lLineNumbers
         cInfo += "Num Off" + hb_OSNewLine()
      ENDIF

      IF ! Empty( ::aBreakPoints )
         FOR n := 1 TO Len( ::aBreakPoints )
            cInfo += "BP " + LTrim( Str( ::aBreakPoints[ n ][ 1 ] ) ) + " " + ;
                     AllTrim( ::aBreakPoints[ n ][ 2 ] ) + hb_OSNewLine()
         NEXT
      ENDIF

      /* This part of the script must be executed after all windows are created */
      FOR n := 1 TO Len( ::aWindows )
         oWnd := ::aWindows[ n ]
         cInfo += "Window Size " + LTrim( Str( oWnd:nBottom - oWnd:nTop + 1 ) ) + " "
         cInfo += LTrim( Str( oWnd:nRight - oWnd:nLeft + 1 ) ) + hb_OSNewLine()
         cInfo += "Window Move " + LTrim( Str( oWnd:nTop ) ) + " "
         cInfo += LTrim( Str( oWnd:nLeft ) ) + hb_OSNewLine()
         cInfo += "Window Next" + hb_OSNewLine()
      NEXT

      MemoWrit( ::cSettingsFileName, cInfo )
   ENDIF

   RETURN NIL
debugger.prg2334
HBDEBUGGER:METHODSearchLine() CLASS HBDebugger
METHOD SearchLine() CLASS HBDebugger

   LOCAL cLine := ::InputBox( "Line number", "1" )

   IF Val( cLine ) > 0
      ::GotoLine ( Val( cLine ) )
   ENDIF

   RETURN NIL
debugger.prg2428
HBDEBUGGER:METHODShow() CLASS HBDebugger
METHOD Show() CLASS HBDebugger

   ::SaveAppScreen()
   ::oPullDown:Display()
   ::oWndCode:Show( .T. )
   ::oWndCommand:Show()
   DispOutAt( ::oWndCommand:nBottom - 1, ::oWndCommand:nLeft + 1, ">" )

   ::BarDisplay()

   RETURN NIL
debugger.prg2439
HBDEBUGGER:METHODShowAllGlobals() CLASS HBDebugger
METHOD ShowAllGlobals() CLASS HBDebugger

   ::lShowAllGlobals := ! ::lShowAllGlobals
   ::RefreshVars()

   RETURN NIL
debugger.prg2452
HBDEBUGGER:METHODShowAppScreen() CLASS HBDebugger
METHOD ShowAppScreen() CLASS HBDebugger

   ::CloseDebuggerWindow()

   IF LastKey() == K_LBUTTONDOWN
      Inkey( 0, INKEY_ALL )
   ENDIF
   DO WHILE Inkey( 0, INKEY_ALL ) == K_MOUSEMOVE
   ENDDO

   ::OpenDebuggerWindow()

   RETURN NIL
debugger.prg2460
HBDEBUGGER:METHODShowCallStack() CLASS HBDebugger
METHOD ShowCallStack() CLASS HBDebugger

   ::lShowCallStack := .T.

   IF ::oWndStack == NIL

      SetCursor( SC_NONE )

      DispBegin()
      // Resize code window
      ::oWndCode:Resize(,,, ::oWndCode:nRight - 16 )
      // Resize vars window
      IF ::oWndVars != NIL
         ::oWndVars:Resize(,,, ::oWndVars:nRight - 16 )
      ENDIF
      // Resize watchpoints window
      IF ::oWndPnt != NIL
         ::oWndPnt:Resize(,,, ::oWndPnt:nRight - 16)
      ENDIF
      DispEnd()

      IF ::aWindows[ ::nCurrentWindow ]:lFocused
         ::aWindows[ ::nCurrentWindow ]:Show( .F. )
      ENDIF

      ::oWndStack := HBDbWindow():New( 1, ::nMaxCol - 15, ::nMaxRow - 6, ::nMaxCol,;
                                     "Calls" )
      ::oWndStack:bKeyPressed  := { | nKey | ::CallStackProcessKey( nKey ) }
      ::oWndStack:bLButtonDown := { || ::CallStackProcessKey( K_LBUTTONDOWN ) }

      AAdd( ::aWindows, ::oWndStack )
      //::nCurrentWindow := Len( ::aWindows )

      IF ::oBrwStack == NIL
         ::BuildBrowseStack()
      ENDIF

      ::oWndStack:bPainted := { || ::oBrwStack:ColorSpec := __DbgColors()[ 2 ] + "," + ;
                                  __DbgColors()[ 5 ] + "," + __DbgColors()[ 4 ],;
                                  ::oBrwStack:RefreshAll(), ::oBrwStack:ForceStable() }
      ::oWndStack:bGotFocus := { || SetCursor( SC_NONE ) }

      ::oWndStack:Show( .F. )
   ENDIF

   RETURN NIL
debugger.prg2475
HBDEBUGGER:METHODShowCodeLine( nProc ) CLASS HBDebugger
METHOD ShowCodeLine( nProc ) CLASS HBDebugger

   LOCAL cDir
   LOCAL cName
   LOCAL nLine
   LOCAL cPrgName

   // we only update the stack window and up a new browse
   // to view the code if we have just broken execution
   IF !::lGo
      IF ::oWndStack != NIL
         ::oBrwStack:RefreshAll()
      ENDIF

      nLine := ::aProcStack[ nProc ][ CSTACK_LINE ]
      cPrgName := ::aProcStack[ nProc ][ CSTACK_MODULE ]
      IF nLine == NIL
         ::oBrwText := NIL
         ::oWndCode:Browser := NIL
         ::oWndCode:SetCaption( ::aProcStack[ nProc ][ CSTACK_FUNCTION ] +;
                                ": Code not available" )
         ::oWndCode:Refresh() // to force the window caption to update
         RETURN NIL
      ENDIF

      IF ::lPPO
         hb_FNameSplit( cPrgName, @cDir, @cName, NIL )
         cPrgName := hb_FNameMerge( cDir, cName, ".ppo" )
      ENDIF

      IF ! Empty( cPrgName )

         IF !hb_FileMatch( strip_path( cPrgName ), strip_path( ::cPrgName ) ) ;
              .OR. ::oBrwText == NIL

            IF ! File( cPrgName ) .AND. !Empty( ::cPathForFiles )
               cPrgName := ::LocatePrgPath( cPrgName )
            ENDIF

            ::cPrgName := cPrgName

            IF !File( cPrgName )
               ::oBrwText := NIL
               ::oWndCode:Browser := NIL
               ::oWndCode:SetCaption( ::aProcStack[ nProc ][ CSTACK_MODULE ] + ;
                                     "  File not found" )
               ::oWndCode:Refresh()
               RETURN NIL
            ENDIF

            IF ::oBrwText == NIL
               ::oBrwText := HBBrwText():New( ::oWndCode:nTop + 1, ::oWndCode:nLeft + 1,;
                                              ::oWndCode:nBottom - 1, ::oWndCode:nRight - 1, cPrgName,;
                                              __DbgColors()[ 2 ] + "," + __DbgColors()[ 5 ] + "," + ;
                                              __DbgColors()[ 3 ] + "," + __DbgColors()[ 6 ], ;
                                              ::lLineNumbers, ::nTabWidth )

               ::oWndCode:Browser := ::oBrwText

            ELSE
               ::oBrwText:LoadFile(cPrgName)
            ENDIF

            ::oWndCode:bPainted := { || iif( ::oBrwText != NIL, ::oBrwText:RefreshAll():ForceStable(), ::oWndCode:Clear() ) }
            ::RedisplayBreakpoints()               // check for breakpoints in this file and display them
            ::oWndCode:SetCaption( ::cPrgName )
            ::oWndCode:Refresh()       // to force the window caption to update
         ENDIF
         ::oBrwText:SetActiveLine( nLine )
         ::GotoLine( nLine )
      ENDIF

   ENDIF

   RETURN NIL
debugger.prg2523
HBDEBUGGER:METHODShowHelp( nTopic ) CLASS HBDebugger
METHOD ShowHelp( nTopic ) CLASS HBDebugger

   LOCAL nCursor := SetCursor( SC_NONE )

   __dbgHelp( nTopic )
   SetCursor( nCursor )

   RETURN NIL
debugger.prg2600
HBDEBUGGER:METHODShowVars() CLASS HBDebugger
METHOD ShowVars() CLASS HBDebugger

   LOCAL nWidth
   LOCAL oCol
   LOCAL lRepaint := .F.
   LOCAL nTop
   LOCAL nBottom
   LOCAL lWindowCreated := .F.

   IF ::lGo
      RETURN NIL
   ENDIF

   IF ! ( ::lShowLocals .OR. ::lShowStatics .OR. ::lShowPrivates .OR. ;
          ::lShowPublics .OR. ::lShowGlobals )
      RETURN NIL
   ENDIF

   DispBegin()

   IF ::oWndVars == NIL

      nTop := iif( ::oWndPnt != NIL .AND. ::oWndPnt:lVisible, ::oWndPnt:nBottom + 1,1)
      nBottom := nTop + Min( MAX_VARS_HEIGHT, Len( ::aVars ) + 1 )

      ::oWndVars := HBDbWindow():New( nTop, 0, nBottom,;
         ::nMaxCol - iif( ::oWndStack != NIL, ::oWndStack:nWidth(), 0 ),;
         "Monitor:" + ;
         iif( ::lShowGlobals, " Global", "" ) + iif( ::lShowLocals, " Local", "" ) + ;
         iif( ::lShowStatics, " Static", "" ) + iif( ::lShowPrivates, " Private", "" ) + ;
         iif( ::lShowPublics, " Public", "" ) )

      ::oWndVars:bLButtonDown := { | nMRow, nMCol | ::WndVarsLButtonDown( nMRow, nMCol ) }
      ::oWndVars:bLDblClick   := { || ::EditVar( ::oBrwVars:Cargo[ 1 ] ) }
      ::oWndVars:bPainted     := { || iif(Len( ::aVars ) > 0, ( ::oBrwVars:RefreshAll():ForceStable(),RefreshVarsS(::oBrwVars) ),) }

      ::oWndVars:bKeyPressed := { | nKey | iif( Len( ::aVars ) == 0, NIL, ( ;
      iif( nKey == K_DOWN, ::oBrwVars:Down(), NIL ) ;
      , iif( nKey == K_UP, ::oBrwVars:Up(), NIL ) ;
      , iif( nKey == K_PGDN, ::oBrwVars:PageDown(), NIL ) ;
      , iif( nKey == K_PGUP, ::oBrwVars:PageUp(), NIL ) ;
      , iif( nKey == K_HOME, ::oBrwVars:GoTop(), NIL ) ;
      , iif( nKey == K_END, ::oBrwVars:GoBottom(), NIL ) ;
      , iif( nKey == K_ENTER, ::EditVar( ::oBrwVars:Cargo[ 1 ] ), NIL ), ;
      iif(Len(::aVars)>0, ::oBrwVars:ForceStable(), NIL) ) ) }

      AAdd( ::aWindows, ::oWndVars )
      lWindowCreated := .T.
   ELSE

      nTop := ::oWndVars:nTop
      ::oWndVars:cCaption := "Monitor:" + ;
      iif( ::lShowGlobals, " Global", "" ) + ;
      iif( ::lShowLocals, " Local", "" ) + ;
      iif( ::lShowStatics, " Static", "" ) + ;
      iif( ::lShowPrivates, " Private", "" ) + ;
      iif( ::lShowPublics, " Public", "" )

      nBottom := ::oWndVars:nBottom
      IF Len( ::aVars ) == 0
         IF ::oWndVars:nBottom - ::oWndVars:nTop > 1
            nBottom := nTop + 1
         ENDIF
      ELSEIF Len( ::aVars ) > ::oWndVars:nBottom - ::oWndVars:nTop - 1
         nBottom := nTop + Min( Len( ::aVars ) + 1, MAX_VARS_HEIGHT )
      ELSEIF Len( ::aVars ) < ::oWndVars:nBottom - ::oWndVars:nTop - 1
         nBottom := nTop + Len( ::aVars ) + 1
      ELSE
         nBottom := ::oWndVars:nBottom
      ENDIF
   ENDIF

   IF Len( ::aVars ) > 0 .AND. ::oBrwVars == NIL
      ::oBrwVars := HBDbBrowser():New( nTop + 1, 1, nBottom - 1, ;
                                       ::nMaxCol - iif( ::oWndStack != NIL, ::oWndStack:nWidth(), 0 ) - 1 )

      ::oBrwVars:Cargo := { 1, {} } // Actual highlighted row
      ::oBrwVars:ColorSpec := ::aColors[ 2 ] + "," + ::aColors[ 5 ] + "," + ::aColors[ 3 ]
      ::oBrwVars:goTopBlock := { || ::oBrwVars:cargo[ 1 ] := Min( 1, Len( ::aVars ) ) }
      ::oBrwVars:goBottomBlock := { || ::oBrwVars:cargo[ 1 ] := Max( 1, Len( ::aVars ) ) }
      ::oBrwVars:skipBlock := { | nSkip, nOld | ;
                               nOld := ::oBrwVars:Cargo[ 1 ],;
                               ::oBrwVars:Cargo[ 1 ] += nSkip,;
                               ::oBrwVars:Cargo[ 1 ] := Min( Max( ::oBrwVars:Cargo[ 1 ], 1 ), Len( ::aVars ) ),;
                               ::oBrwVars:Cargo[ 1 ] - nOld }

      nWidth := ::oWndVars:nWidth() - 1
      oCol := TBColumnNew( "", ;
           { || PadR( LTrim( Str( ::oBrwVars:Cargo[ 1 ] - 1 ) ) + ") " + ;
                      ::VarGetInfo( ::aVars[ Max( ::oBrwVars:Cargo[ 1 ], 1 ) ] ), ;
                      ::oWndVars:nWidth() - 2 ) } )
      ::oBrwVars:AddColumn( oCol )
      AAdd( ::oBrwVars:Cargo[ 2 ], ::aVars )
      oCol:DefColor := { 1, 2 }
      ::oBrwVars:ForceStable()
   ELSEIF Len( ::aVars ) == 0
      ::oBrwVars := NIL
      ::oWndVars:Browser := NIL
   ENDIF

   ::oWndVars:Browser := ::oBrwVars

   IF lWindowCreated
      ::oWndVars:Show()
      ::ResizeWindows( ::oWndVars )

   ELSE

      IF ::oBrwVars != NIL
         IF ::oBrwVars:cargo[ 1 ] <= 0
            ::oBrwVars:cargo[ 1 ] := 1
         ENDIF
      ENDIF

      IF Len( ::aVars ) == 0
         IF nBottom == ::oWndVars:nBottom
            /* We still need to redraw window caption, it could have changed */
            ::oWndVars:Refresh()
         ENDIF
      ENDIF
      IF nBottom != ::oWndVars:nBottom
         ::oWndVars:Resize( ,, nBottom )
         lRepaint := .T.
      ELSE
         IF ::oBrwVars != NIL
           ::oBrwVars:RefreshAll():ForceStable()
         ENDIF
         ::oWndVars:Refresh()
      ENDIF
      IF ! ::oWndVars:lVisible .OR. lRepaint
         ::ResizeWindows( ::oWndVars )
      ENDIF
   ENDIF

   DispEnd()

   RETURN NIL
debugger.prg2612
HBDEBUGGER:METHODStack() CLASS HBDebugger
METHOD Stack() CLASS HBDebugger

   ::lShowCallStack := ! ::lShowCallStack
   ::oPulldown:GetItemByIdent( "CALLSTACK" ):checked := ::lShowCallStack

   IF ::lActive
      IF ::lShowCallStack
         ::ShowCallStack()
      ELSE
         ::HideCallStack()
      ENDIF
   ENDIF

   RETURN NIL
debugger.prg2751
HBDEBUGGER:METHODStatic() CLASS HBDebugger
METHOD Static() CLASS HBDebugger

   ::lShowStatics := ! ::lShowStatics
   ::RefreshVars()

   RETURN NIL
debugger.prg2767
HBDEBUGGER:METHODStep() CLASS HBDebugger
METHOD Step() CLASS HBDebugger

   // we are starting to run again so reset to the deepest call if displaying stack
   IF ! ::oBrwStack == NIL
      ::oBrwStack:GoTop()
   ENDIF

   ::RestoreAppScreen()
   ::RestoreAppState()
   ::Exit()

   RETURN NIL
debugger.prg2775
HBDEBUGGER:METHODToCursor() CLASS HBDebugger
METHOD ToCursor() CLASS HBDebugger

   IF ::IsValidStopLine( strip_path( ::cPrgName ), ::oBrwText:RowPos() )
      __dbgSetToCursor( ::pInfo, strip_path( ::cPrgName ), ::oBrwText:RowPos() )
      ::RestoreAppScreen()
      ::RestoreAppState()
      ::Exit()
   ENDIF

   RETURN Self
debugger.prg2789
HBDEBUGGER:METHODToggleBreakPoint( nLine, cFileName ) CLASS HBDebugger
METHOD ToggleBreakPoint( nLine, cFileName ) CLASS HBDebugger

   // look for a breakpoint which matches both line number and program name

   LOCAL nAt

   IF !::lActive
      RETURN NIL
   ENDIF

   IF nLine == NIL
      cFileName := strip_path( ::cPrgName )
      nLine := ::oBrwText:RowPos()
   ENDIF

   IF !::IsValidStopLine( cFileName, nLine )
      RETURN NIL
   ENDIF

   nAt := AScan( ::aBreakPoints, { | aBreak | aBreak[ 1 ] == nLine ;
                                     .AND. hb_FileMatch( aBreak[ 2 ], cFileName ) } )

   IF nAt == 0
      AAdd( ::aBreakPoints, { nLine, cFileName } )     // it was nLine
      __dbgAddBreak( ::pInfo, cFileName, nLine )
      IF hb_FileMatch( cFileName, strip_path( ::cPrgName ) )
         ::oBrwText:ToggleBreakPoint( nLine, .T. )
      ENDIF
   ELSE
      ADel( ::aBreakPoints, nAt )
      ASize( ::aBreakPoints, Len( ::aBreakPoints ) - 1 )
      __dbgDelBreak( ::pInfo, nAt - 1 )
      IF hb_FileMatch( cFileName, strip_path( ::cPrgName ) )
         ::oBrwText:ToggleBreakPoint( nLine, .F. )
      ENDIF
   ENDIF

   ::oBrwText:RefreshCurrent()

   RETURN NIL
debugger.prg2803
HBDEBUGGER:METHODTrace() CLASS HBDebugger
METHOD Trace() CLASS HBDebugger

   __dbgSetTrace( ::pInfo )
   ::Step() //forces a Step()

   RETURN Self
debugger.prg2845
HBDEBUGGER:METHODTracepointAdd( cExpr ) CLASS HBDebugger
METHOD TracepointAdd( cExpr ) CLASS HBDebugger

   LOCAL aWatch

   IF cExpr == NIL
      cExpr := Space( 255 )
      cExpr := AllTrim( ::InputBox( "Enter Tracepoint", cExpr ) )
      IF LastKey() == K_ESC
         RETURN Self
      ENDIF
   ENDIF
   cExpr := AllTrim( cExpr )
   IF Empty( cExpr )
      RETURN Self
   ENDIF
   aWatch := { "tp", cExpr, NIL }
   ::RestoreAppState()
   __dbgAddWatch( ::pInfo, cExpr, .T. )
   ::SaveAppState()
   AAdd( ::aWatch, aWatch )
   ::WatchpointsShow()

   RETURN Self
debugger.prg2853
HBDEBUGGER:METHODVarGetInfo( aVar ) 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

   // ; Never reached

   RETURN ""
debugger.prg2878
HBDEBUGGER:METHODVarGetValue( 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

   // ; Never reached

   RETURN NIL
debugger.prg2895
HBDEBUGGER:METHODVarSetValue( aVar, uValue ) CLASS HBDebugger
METHOD VarSetValue( aVar, uValue ) CLASS HBDebugger

   LOCAL nProcLevel
   LOCAL cType := Left( aVar[ VAR_TYPE ], 1 )

   IF cType == "G"
     __dbgvmVarGSet( aVar[ VAR_LEVEL ], aVar[ VAR_POS ], uValue )

   ELSEIF cType == "L"
     nProcLevel := __dbgprocLevel() - aVar[ VAR_LEVEL ]   //skip debugger stack
     __dbgvmVarLSet( nProcLevel, aVar[ VAR_POS ], uValue )

   ELSEIF cType == "S"
     __dbgvmVarSSet( aVar[ VAR_LEVEL ], aVar[ VAR_POS ], uValue )

   ELSE
     // Public or Private
     aVar[ VAR_POS ] := uValue
     &( aVar[ VAR_NAME ] ) := uValue

   ENDIF

   RETURN Self
debugger.prg2911
HBDEBUGGER:METHODViewSets() CLASS HBDebugger
METHOD ViewSets() CLASS HBDebugger

   LOCAL oWndSets := HBDbWindow():New( 1, 8, ::nMaxRow - 2, ::nMaxCol - 8,;
                                      "System Settings[1..47]", ::ClrModal() )
   LOCAL aSets := { "Exact", "Fixed", "Decimals", "DateFormat", "Epoch", "Path",;
                    "Default", "Exclusive", "SoftSeek", "Unique", "Deleted",;
                    "Cancel", "Debug", "TypeAhead", "Color", "Cursor", "Console",;
                    "Alternate", "AltFile", "Device", "Extra", "ExtraFile",;
                    "Printer", "PrintFile", "Margin", "Bell", "Confirm", "Escape",;
                    "Insert", "Exit", "Intensity", "ScoreBoard", "Delimeters",;
                    "DelimChars", "Wrap", "Message", "MCenter", "ScrollBreak",;
                    "EventMask", "VideoMode", "MBlockSize", "MFileExt",;
                    "StrictRead", "Optimize", "Autopen", "Autorder", "AutoShare" }

   LOCAL oBrwSets := HBDbBrowser():new( oWndSets:nTop + 1, oWndSets:nLeft + 1,;
                                        oWndSets:nBottom - 1, oWndSets:nRight - 1 )
   LOCAL nWidth := oWndSets:nRight - oWndSets:nLeft - 1
   LOCAL oCol

   oBrwSets:Cargo := { 1, {} } // Actual highlighted row
   oBrwSets:autolite := .F.
   oBrwSets:ColorSpec := ::ClrModal()
   oBrwSets:goTopBlock := { || oBrwSets:cargo[ 1 ] := 1 }
   oBrwSets:goBottomBlock := { || oBrwSets:cargo[ 1 ] := Len( oBrwSets:cargo[ 2 ][ 1 ] ) }
   oBrwSets:skipBlock := { | nPos | ( nPos := ArrayBrowseSkip( nPos, oBrwSets ), oBrwSets:cargo[ 1 ] := ;
   oBrwSets:cargo[ 1 ] + nPos, nPos ) }
   oBrwSets:AddColumn( oCol := TBColumnNew( "", { || PadR( aSets[ oBrwSets:cargo[ 1 ] ], 12 ) } ) )
   AAdd( oBrwSets:Cargo[ 2 ], aSets )
   ocol:defcolor := { 1, 2 }
   oBrwSets:AddColumn( oCol := TBColumnNew( "",;
                       { || PadR( __dbgValToStr( Set( oBrwSets:cargo[ 1 ]  ) ), nWidth - 13 ) } ) )
   ocol:defcolor := { 1, 3 }
   ocol:width := 40
   oWndSets:bPainted := { || oBrwSets:ForceStable(), RefreshVarsS( oBrwSets ) }
   oWndSets:bKeyPressed := { | nKey | SetsKeyPressed( nKey, oBrwSets, Len( aSets ),;
                            oWndSets, "System Settings",;
                            { || ::EditSet( oBrwSets:Cargo[ 1 ], oBrwSets ) } ) }

   SetCursor( SC_NONE )
   oWndSets:ShowModal()

   RETURN NIL
debugger.prg2936
HBDEBUGGER:METHODWatchGetInfo( nWatch ) CLASS HBDebugger
METHOD WatchGetInfo( nWatch ) CLASS HBDebugger

   LOCAL xVal
   LOCAL cType
   LOCAL lValid
   LOCAL aWatch := ::aWatch[ nWatch ]

   ::RestoreAppState()
   xVal := ::GetExprValue( nWatch, @lValid )
   ::SaveAppState()

   IF lValid
      cType := ValType( xVal )
      xVal  := __dbgValToStr( xVal )
   ELSE
      // xVal contains error description
      cType := "U"
      // xVal := "Undefined"
   ENDIF

   RETURN aWatch[ WP_EXPR ] + " <" + aWatch[ WP_TYPE ] + ", " + cType + ">: " + xVal
debugger.prg2980
HBDEBUGGER:METHODWatchpointAdd( cExpr ) CLASS HBDebugger
METHOD WatchpointAdd( cExpr ) CLASS HBDebugger

   LOCAL aWatch

   IF cExpr == NIL

      cExpr := Space( 255 )
      cExpr := AllTrim( ::InputBox( "Enter Watchpoint", cExpr ) )

      IF LastKey() == K_ESC
         RETURN Self
      ENDIF
   ENDIF

   cExpr := AllTrim( cExpr )

   IF Empty( cExpr )
      RETURN Self
   ENDIF

   aWatch := { "wp", cExpr }
   __dbgAddWatch( ::pInfo, cExpr, .F. )
   AAdd( ::aWatch, aWatch )
   ::WatchpointsShow()

   RETURN Self
debugger.prg3003
HBDEBUGGER:METHODWatchpointDel( nPos ) CLASS HBDebugger
METHOD WatchpointDel( nPos ) CLASS HBDebugger

   IF ::oWndPnt != NIL .AND. ::oWndPnt:lVisible
      IF nPos == NIL
         // called from the menu
         nPos := ::InputBox( "Enter item number to delete", ::oBrwPnt:cargo[ 1 ] - 1 )
      ELSE
         nPos--
      ENDIF
      IF LastKey() != K_ESC
         IF nPos >=0 .AND. nPos < Len( ::aWatch )
            ::oBrwPnt:gotop()
            __dbgDelWatch( ::pInfo, nPos )
            ADel( ::aWatch, nPos + 1 )
            ASize( ::aWatch, Len( ::aWatch ) - 1 )
            IF Len( ::aWatch ) == 0
               ::WatchpointsHide()
            ELSE
               ::WatchpointsShow()
            ENDIF
         ENDIF
      ENDIF
   ENDIF

   RETURN Self
debugger.prg3031
HBDEBUGGER:METHODWatchpointEdit( nPos ) CLASS HBDebugger
METHOD WatchpointEdit( nPos ) CLASS HBDebugger

   LOCAL cExpr
   LOCAL aWatch

   cExpr := PadR( ::aWatch[ nPos ][ WP_EXPR ], 255 )
   cExpr := AllTrim( ::InputBox( "Enter Watchpoint", cExpr ) )

   IF LastKey() == K_ESC
      RETURN Self
   ENDIF

   cExpr := AllTrim( cExpr )

   IF Empty( cExpr )
      RETURN Self
   ENDIF

   aWatch := { "wp", cExpr }

   __dbgSetWatch( ::pInfo, nPos - 1, cExpr, .F. )
   ::aWatch[ nPos ] := aWatch
   ::WatchpointsShow()

   RETURN Self
debugger.prg3058
HBDEBUGGER:METHODWatchpointInspect( nPos ) CLASS HBDebugger
METHOD WatchpointInspect( nPos ) CLASS HBDebugger

   LOCAL xValue
   LOCAL lValid

   ::RestoreAppState()
   xValue := ::GetExprValue( ::aWatch[ nPos ][ WP_EXPR ], @lValid )
   ::SaveAppState()

   ::InputBox( ::aWatch[ nPos ][ WP_EXPR ], xValue, NIL, .F. )
   ::RefreshVars()

   RETURN Self
debugger.prg3085
HBDEBUGGER:METHODWatchpointsHide() CLASS HBDebugger
METHOD WatchpointsHide() CLASS HBDebugger

   ::oWndPnt:Hide()
   ::oWndCode:nTop := iif( ::oWndVars != NIL .AND. ::oWndVars:lVisible, ::oWndVars:nBottom + 1, 1 )
   ::oBrwText:Resize( ::oWndCode:nTop + 1 )
   IF ::aWindows[ ::nCurrentWindow ] == ::oWndPnt
      ::NextWindow()
   ENDIF

   RETURN NIL
debugger.prg3100
HBDEBUGGER:METHODWatchpointsShow() CLASS HBDebugger
METHOD WatchpointsShow() CLASS HBDebugger

   LOCAL nWidth
   LOCAL oCol
   LOCAL lRepaint := .F.
   LOCAL nTop

   IF ::lGo
      RETURN NIL
   ENDIF

   IF Len( ::aWatch ) == 0
      RETURN NIL
   ENDIF

   IF ::oWndPnt == NIL

      nTop := iif( ::oWndVars != NIL .AND. ::oWndVars:lVisible, ::oWndVars:nBottom, 0 ) + 1

      ::oWndPnt := HBDbWindow():New( nTop,;
         0, ;
         nTop + Min( 4, Len( ::aWatch ) ) + 1,;
         ::nMaxCol - iif( ::oWndStack != NIL, ::oWndStack:nWidth(), 0 ),;
         "Watch" )

//      ::oBrwText:Resize( ::oWndPnt:nBottom + 1 )
//      ::oWndCode:nTop := ::oWndPnt:nBottom + 1
//      ::oBrwText:Resize( ::oWndCode:nTop + 1 )
//      ::oBrwText:RefreshAll()
//      ::oWndCode:SetFocus( .T. )

//      ::oWndPnt:bLButtonDown := { | nMRow, nMCol | ::WndVarsLButtonDown( nMRow, nMCol ) }
//      ::oWndPnt:bLDblClick   := { | nMRow, nMCol | ::EditVar( ::oBrwPnt:Cargo[ 1 ] ) }

      ::oBrwPnt := HBDbBrowser():New( nTop + 1, 1, ::oWndPnt:nBottom - 1, ::nMaxCol - iif( ::oWndStack != NIL,;
                               ::oWndStack:nWidth(), 0 ) - 1 )

      ::oWndPnt:Browser := ::oBrwPnt

      ::oBrwPnt:Cargo := { 1, {} } // Actual highlighted row
      ::oBrwPnt:ColorSpec := ::aColors[ 2 ] + "," + ::aColors[ 5 ] + "," + ::aColors[ 3 ]
      ::oBrwPnt:goTopBlock := { || ::oBrwPnt:cargo[ 1 ] := Min( 1, Len(::aWatch ) ) }
      ::oBrwPnt:goBottomBlock := { || ::oBrwPnt:cargo[ 1 ] := Len( ::aWatch ) }
      ::oBrwPnt:skipBlock := { | nSkip, nOld | nOld := ::oBrwPnt:Cargo[ 1 ],;
                               ::oBrwPnt:Cargo[ 1 ] += nSkip,;
                               ::oBrwPnt:Cargo[ 1 ] := Min( Max( ::oBrwPnt:Cargo[ 1 ], 1 ),;
                                                             Len( ::aWatch ) ),;
                               iif( Len(::aWatch) > 0, ::oBrwPnt:Cargo[ 1 ] - nOld, 0 ) }

      nWidth := ::oWndPnt:nWidth() - 1
      oCol := TBColumnNew( "", ;
         { || PadR( iif( Len( ::aWatch ) > 0, ;
                       LTrim( Str( ::oBrwPnt:Cargo[ 1 ] - 1 ) ) + ") " + ;
                       ::WatchGetInfo( Max( ::oBrwPnt:Cargo[ 1 ], 1 ) ), ;
                       " " ), ;
                   ::oWndPnt:nWidth() - 2 ) } )
      ::oBrwPnt:AddColumn( oCol )
      AAdd( ::oBrwPnt:Cargo[ 2 ], ::aWatch)
      oCol:DefColor := { 1, 2 }

      ::oWndPnt:bPainted := { || iif( Len( ::aWatch ) > 0, ( ::oBrwPnt:RefreshAll():ForceStable(), RefreshVarsS( ::oBrwPnt ) /*, ::RefreshVars()*/ ) , ) }

      ::oWndPnt:bKeyPressed := { | nKey | ;
      ( iif( nKey == K_DOWN, ::oBrwPnt:Down(), NIL ) ;
      , iif( nKey == K_UP, ::oBrwPnt:Up(), NIL ) ;
      , iif( nKey == K_PGDN, ::oBrwPnt:PageDown(), NIL ) ;
      , iif( nKey == K_PGUP, ::oBrwPnt:PageUp(), NIL ) ;
      , iif( nKey == K_HOME, ::oBrwPnt:GoTop(), NIL ) ;
      , iif( nKey == K_END, ::oBrwPnt:GoBottom(), NIL ) ;
      , iif( nKey == K_DEL, ::WatchpointDel( ::oBrwPnt:Cargo[ 1 ] ), NIL ) ;
      , iif( nKey == K_ENTER, ::WatchpointEdit( ::oBrwPnt:Cargo[ 1 ] ), NIL ) ;
      , iif( nKey == K_CTRL_ENTER, ::WatchpointInspect( ::oBrwPnt:Cargo[ 1 ] ), NIL ) ;
      , ::oBrwPnt:ForceStable() ) }

      AAdd( ::aWindows, ::oWndPnt )
      ::oWndPnt:Show()
      ::ResizeWindows( ::oWndPnt )
   ELSE
      IF ::oBrwPnt:cargo[ 1 ] <= 0
         ::oBrwPnt:cargo[ 1 ] := 1
      ENDIF
      DispBegin()
      IF Len( ::aWatch ) > ::oWndPnt:nBottom - ::oWndPnt:nTop - 1
         //Resize( top, left, bottom, right )
         ::oWndPnt:Resize( ,, ::oWndPnt:nTop + Min( Len( ::aWatch ) + 1, 4 ) )
         lRepaint := .T.
      ELSEIF Len( ::aWatch ) < ::oWndPnt:nBottom - ::oWndPnt:nTop - 1
         ::oWndPnt:Resize( ,, ::oWndPnt:nTop + Len( ::aWatch ) + 1 )
         lRepaint := .T.
      ELSE
         ::oBrwPnt:RefreshAll():ForceStable()
      ENDIF
      IF ! ::oWndPnt:lVisible .OR. lRepaint
         ::ResizeWindows( ::oWndPnt )
      ENDIF
      DispEnd()
   ENDIF

   RETURN NIL
debugger.prg3112
HBDEBUGGER:METHODWndVarsLButtonDown( nMRow, nMCol ) CLASS HBDebugger
METHOD WndVarsLButtonDown( nMRow, nMCol ) CLASS HBDebugger

   IF nMRow > ::oWndVars:nTop .AND. ;
      nMRow < ::oWndVars:nBottom .AND. ;
      nMCol > ::oWndVars:nLeft .AND. ;
      nMCol < ::oWndVars:nRight

      IF nMRow - ::oWndVars:nTop >= 1 .AND. ;
         nMRow - ::oWndVars:nTop <= Len( ::aVars )

         DO WHILE ::oBrwVars:RowPos > nMRow - ::oWndVars:nTop
            ::oBrwVars:Up()
            ::oBrwVars:ForceStable()
         ENDDO

         DO WHILE ::oBrwVars:RowPos < nMRow - ::oWndVars:nTop
            ::oBrwVars:Down()
            ::oBrwVars:ForceStable()
         ENDDO

      ENDIF
   ENDIF

   RETURN NIL
debugger.prg3213
STATIC PROCEDURESetsKeyPressed( nKey, oBrwSets, nSets, oWnd, cCaption, bEdit )
STATIC PROCEDURE SetsKeyPressed( nKey, oBrwSets, nSets, oWnd, cCaption, bEdit )

   DO CASE
   CASE nKey == K_UP

      oBrwSets:up()

   CASE nKey == K_DOWN

      oBrwSets:down()

   CASE nKey == K_HOME .OR. nKey == K_CTRL_PGUP .OR. nKey == K_CTRL_HOME

      oBrwSets:goTop()

   CASE nKey == K_END .OR. nKey == K_CTRL_PGDN .OR. nKey == K_CTRL_END

      oBrwSets:goBottom()

   CASE nKey == K_PGDN

      oBrwSets:pageDown()

   CASE nKey == K_PGUP

      oBrwSets:pageUp()

   CASE nKey == K_ENTER

      IF bEdit != NIL
         Eval( bEdit )
      ENDIF

      IF LastKey() == K_ENTER
         KEYBOARD Chr( K_DOWN )
      ENDIF

   ENDCASE

   RefreshVarsS( oBrwSets )

   oWnd:SetCaption( cCaption + "[" + RTrim( Str( oBrwSets:Cargo[ 1 ] ) ) + ".." + RTrim( Str( nSets ) ) + "]" )

   RETURN
debugger.prg3239
STATIC PROCEDUREStripUntil( pcLine, i, cChar )
STATIC PROCEDURE StripUntil( pcLine, i, cChar )

   LOCAL j
   LOCAL n
   LOCAL nLen := Len( pcLine )

   n := Len( cChar )
   j := i + n
   DO WHILE j <= nLen .AND. SubStr( pcLine, j, n ) != cChar
      j++
   ENDDO

   IF j <= nLen
      pcLine := Left( pcLine, i - 1 ) + SubStr( pcLine, j + n )
   ENDIF

   RETURN
debugger.prg3285
FUNCTION__DbgColors()
FUNCTION __DbgColors()
   RETURN iif( ! s_oDebugger:lMonoDisplay,;
             s_oDebugger:aColors,;
             { "W+/N", "W+/N", "N/W", "N/W", "N/W", "N/W", "W+/N", "N/W", "W+/W", "W/N", "W+/N" } )
debugger.prg3304
FUNCTION__Dbg()
FUNCTION __Dbg()
   RETURN s_oDebugger
debugger.prg3310
STATIC PROCEDURERefreshVarsS( oBrowse )
STATIC PROCEDURE RefreshVarsS( oBrowse )

   LOCAL nLen := oBrowse:colCount

   IF nLen == 2
      oBrowse:deHilite():colPos := 2
   ENDIF
   oBrowse:deHilite():forceStable()

   IF nLen == 2
      oBrowse:hilite():colPos := 1
   ENDIF
   oBrowse:hilite()

   RETURN
debugger.prg3314
STATIC FUNCTIONArrayBrowseSkip( nPos, oBrwSets )
STATIC FUNCTION ArrayBrowseSkip( nPos, oBrwSets )
   RETURN iif( oBrwSets:cargo[ 1 ] + nPos < 1, 0 - oBrwSets:cargo[ 1 ] + 1 , ;
             iif( oBrwSets:cargo[ 1 ] + nPos > Len( oBrwSets:cargo[ 2 ][ 1 ] ), ;
                Len( oBrwSets:cargo[ 2 ][ 1 ] ) - oBrwSets:cargo[ 1 ], nPos ) )
debugger.prg3331
STATIC FUNCTIONPathToArray( cList )
STATIC FUNCTION PathToArray( cList )

   LOCAL aList := {}
   LOCAL cSep := hb_OSPathListSeparator()
   LOCAL cDirSep := hb_OSPathDelimiters()
   LOCAL nPos

   IF cList != NIL

      DO WHILE ( nPos := At( cSep, cList ) ) != 0
         AAdd( aList, SubStr( cList, 1, nPos - 1 ) )        // Add a new element
         cList := SubStr( cList, nPos + 1 )
      ENDDO

      AAdd( aList, cList )              // Add final element

      /* Strip ending delimiters */
      AEval( aList, { | x, i | iif( Right( x, 1 ) $ cDirSep,  aList[ i ] := Left( x, Len( x ) - 1 ), ) } )
   ENDIF

   RETURN aList
debugger.prg3337
STATIC FUNCTIONstarts( cLine, cStart )
STATIC FUNCTION starts( cLine, cStart )
   RETURN cStart == Left( cLine, Len( cStart ) )
debugger.prg3361
STATIC FUNCTIONstrip_path( cFileName )
STATIC FUNCTION strip_path( cFileName )

   LOCAL cName
   LOCAL cExt

   DEFAULT cFileName TO ""

   hb_FNameSplit( cFileName, NIL, @cName, @cExt )

   RETURN cName + cExt
debugger.prg3366
STATIC FUNCTIONgetdbginput( nTop, nLeft, uValue, bValid, cColor )
STATIC FUNCTION getdbginput( nTop, nLeft, uValue, bValid, cColor )

   LOCAL nOldCursor := SetCursor( SC_NORMAL )
   LOCAL uTemp := uValue

   IF cColor != NIL
      SetColor( cColor )
   ENDIF

   DO WHILE .T.
      @ nTop, nLeft SAY Space( Len( uTemp ) )
      @ nTop, nLeft SAY ""

      ACCEPT TO uTemp

      IF bValid != NIL .AND. !Eval( bValid, uTemp )
         uTemp := uValue
      ELSE
         EXIT
      ENDIF
   ENDDO

   SetCursor( nOldCursor )

   RETURN uTemp
debugger.prg3380
FUNCTION__dbgValToStr( uVal )
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 == "N" ; RETURN RTrim( Str( uVal ) )
   CASE cType == "O" ; RETURN "Class " + uVal:ClassName() + " object"
   CASE cType == "H" ; RETURN "Hash of " + RTrim( Str( Len( uVal ) ) ) + " elements"
   CASE cType == "P" ; RETURN "Pointer"
   ENDCASE

   RETURN "U"
debugger.prg3408
tbrwtext.prg
TypeFunctionSourceLine
METHODNew( nTop, nLeft, nBottom, nRight, cFileName, cColor, lLineNumbers, nTabWidth )
   METHOD New( nTop, nLeft, nBottom, nRight, cFileName, cColor, lLineNumbers, nTabWidth )
tbrwtext.prg75
METHODGoTop()
   METHOD GoTop()                                  // Methods available on a standard TBrowse, needed to handle a HBEditor like a TBrowse
tbrwtext.prg77
METHODGoBottom()
   METHOD GoBottom()
tbrwtext.prg78
METHODUp()
   METHOD Up()
tbrwtext.prg79
METHODDown()
   METHOD Down()
tbrwtext.prg80
METHODLeft()
   METHOD Left()
tbrwtext.prg81
METHODRight()
   METHOD Right()
tbrwtext.prg82
METHODEnd()
   METHOD End()
tbrwtext.prg83
METHODPageUp()
   METHOD PageUp()
tbrwtext.prg84
METHODPageDown()
   METHOD PageDown()
tbrwtext.prg85
METHODRefreshAll()
   METHOD RefreshAll()
tbrwtext.prg86
METHODRefreshCurrent()
   METHOD RefreshCurrent()
tbrwtext.prg87
METHODResize( nTop, nLeft, nBottom, nRight )
   METHOD Resize( nTop, nLeft, nBottom, nRight )
tbrwtext.prg88
METHODScrollTo( nCol )
   METHOD ScrollTo( nCol )                         // Scroll the window to specified column
tbrwtext.prg89
METHODForceStable() INLINE NIL
   METHOD ForceStable() INLINE NIL
tbrwtext.prg90
METHODGotoLine( n )
   METHOD GotoLine( n )                            // Moves active line cursor
tbrwtext.prg91
METHODSetActiveLine( n )
   METHOD SetActiveLine( n )                       // Sets the line to be executed
tbrwtext.prg92
METHODGetLine( nRow )
   METHOD GetLine( nRow )                          // Redefine HBEditor method to add line number
tbrwtext.prg93
METHODLineColor( nRow )
   METHOD LineColor( nRow )                        // Redefine HBEditor method to handle line coloring
tbrwtext.prg94
METHODToggleBreakPoint( nRow, lSet )
   METHOD ToggleBreakPoint( nRow, lSet )           // if lSet is .T. there is a BreakPoint active at nRow, if lSet is .F. BreakPoint at nRow has to be removed
tbrwtext.prg95
METHODSearch( cString, lCaseSensitive, nMode )
   METHOD Search( cString, lCaseSensitive, nMode ) // 0 from Begining to end, 1 Forward, 2 Backwards
tbrwtext.prg96
METHODRowPos()
   METHOD RowPos()

   FRIEND CLASS HBDebugger

ENDCLASS
tbrwtext.prg97
HBBRWTEXT:METHODNew( nTop, nLeft, nBottom, nRight, cFileName, cColor, lLineNumbers, nTabWidth ) CLASS HBBrwText
METHOD New( nTop, nLeft, nBottom, nRight, cFileName, cColor, lLineNumbers, nTabWidth ) CLASS HBBrwText

   DEFAULT cColor TO SetColor()
   DEFAULT lLineNumbers TO .T.

   ::cFileName := cFileName
   ::lLineNumbers := lLineNumbers

   ::Super:New( "", nTop, nLeft, nBottom, nRight, .T., NIL, nTabWidth )
   ::Super:SetColor( cColor )
   ::Super:LoadFile( cFileName )

   RETURN Self
tbrwtext.prg103
HBBRWTEXT:METHODGoTop() CLASS HBBrwText
METHOD GoTop() CLASS HBBrwText

   ::MoveCursor( K_CTRL_PGUP )

   RETURN Self
tbrwtext.prg117
HBBRWTEXT:METHODGoBottom() CLASS HBBrwText
METHOD GoBottom() CLASS HBBrwText

   ::MoveCursor( K_CTRL_PGDN )

   RETURN Self
tbrwtext.prg123
HBBRWTEXT:METHODUp() CLASS HBBrwText
METHOD Up() CLASS HBBrwText

   ::MoveCursor( K_UP )

   RETURN Self
tbrwtext.prg129
HBBRWTEXT:METHODLeft() CLASS HBBrwText
METHOD Left() CLASS HBBrwText

   ::MoveCursor( K_LEFT )

   RETURN Self
tbrwtext.prg135
HBBRWTEXT:METHODRight() CLASS HBBrwText
METHOD Right() CLASS HBBrwText

   ::MoveCursor( K_RIGHT )

   RETURN Self
tbrwtext.prg141
HBBRWTEXT:METHODEnd() CLASS HBBrwText
METHOD End() CLASS HBBrwText

   ::MoveCursor( K_END )

   RETURN Self
tbrwtext.prg147
HBBRWTEXT:METHODDown() CLASS HBBrwText
METHOD Down() CLASS HBBrwText

   ::MoveCursor( K_DOWN )

   RETURN Self
tbrwtext.prg153
HBBRWTEXT:METHODPageUp() CLASS HBBrwText
METHOD PageUp() CLASS HBBrwText

   ::MoveCursor( K_PGUP )

   RETURN Self
tbrwtext.prg159
HBBRWTEXT:METHODPageDown() CLASS HBBrwText
METHOD PageDown() CLASS HBBrwText

   ::MoveCursor( K_PGDN )

   RETURN Self
tbrwtext.prg165
HBBRWTEXT:METHODRowPos()
METHOD RowPos()

   RETURN ::nRow
tbrwtext.prg171
HBBRWTEXT:METHODRefreshAll() CLASS HBBrwText
METHOD RefreshAll() CLASS HBBrwText

   ::display()

   RETURN Self
tbrwtext.prg175
HBBRWTEXT:METHODRefreshCurrent() CLASS HBBrwText
METHOD RefreshCurrent() CLASS HBBrwText

   ::RefreshLine()

   return Self
tbrwtext.prg181
HBBRWTEXT:METHODSetActiveLine( n ) CLASS HBBrwText
METHOD SetActiveLine( n ) CLASS HBBrwText

   ::nActiveLine := n
   ::display()

   RETURN Self
tbrwtext.prg187
HBBRWTEXT:METHODGotoLine( n ) CLASS HBBrwText
METHOD GotoLine( n ) CLASS HBBrwText

   ::Super:GotoLine( n )

   RETURN Self
tbrwtext.prg194
HBBRWTEXT:METHODGetLine( nRow ) CLASS HBBrwText
METHOD GetLine( nRow ) CLASS HBBrwText
   RETURN iif( ::lLineNumbers, AllTrim( Str( nRow ) ) + ": ", "" ) + ::Super:GetLine( nRow )
tbrwtext.prg200
HBBRWTEXT:METHODLineColor( nRow ) CLASS HBBrwText
METHOD LineColor( nRow ) CLASS HBBrwText

   LOCAL lHilited := ( nRow == ::nActiveLine )
   LOCAL lBreak := AScan( ::aBreakPoints, nRow ) > 0
   LOCAL nIndex := CLR_CODE

   IF lHilited
      nIndex += CLR_CURSOR
   ENDIF
   IF lBreak
      nIndex += CLR_BKPT
   ENDIF

   RETURN hb_ColorIndex( ::cColorSpec, nIndex )
tbrwtext.prg203
HBBRWTEXT:METHODToggleBreakPoint( nRow, lSet ) CLASS HBBrwText
METHOD ToggleBreakPoint( nRow, lSet ) CLASS HBBrwText

   LOCAL nAt := AScan( ::aBreakPoints, nRow )

   IF lSet
      // add it only if not present
      IF nAt == 0
         AAdd( ::aBreakPoints, nRow )
      ENDIF
   ELSEIF nAt != 0
      ADel( ::aBreakPoints, nAt )
      ASize( ::aBreakPoints, Len( ::aBreakPoints ) - 1 )
   ENDIF

   RETURN Self
tbrwtext.prg218
HBBRWTEXT:METHODResize( nTop, nLeft, nBottom, nRight ) CLASS HBBrwText
METHOD Resize( nTop, nLeft, nBottom, nRight ) CLASS HBBrwText
   LOCAL nRow

   nRow := ::nRow
   ::Super:Resize( nTop, nLeft, nBottom, nRight )
   ::GotoLine( nRow )
RETURN Self
tbrwtext.prg235
HBBRWTEXT:METHODScrollTo( nCol ) CLASS HBBrwText
METHOD ScrollTo( nCol ) CLASS HBBrwText
   IF nCol >= 1
      ::nCol := nCol
      ::nFirstCol := nCol
      ::display()
      ::SetPos( ::Row(), ::nLeft )
   ENDIF
RETURN Self
tbrwtext.prg244
HBBRWTEXT:METHODSearch( cString, lCaseSensitive, nMode ) CLASS HBBrwText
METHOD Search( cString, lCaseSensitive, nMode ) CLASS HBBrwText

   LOCAL nFrom
   LOCAL nTo
   LOCAL nStep
   LOCAL nFor
   LOCAL lFound := .F.

   DEFAULT lCaseSensitive TO .F.
   DEFAULT nMode          TO 0

   IF !lCaseSensitive
      cString := Upper( cString )
   ENDIF

   DO CASE
   CASE nMode == 0 // From Top
      nFrom := 1
      nTo   := ::naTextLen
      nStep := 1
   CASE nMode == 1 // Forward
      nFrom := Min( ::nRow + 1, ::naTextLen )
      nTo   := ::naTextLen
      nStep := 1
   CASE nMode == 2 // Backward
      nFrom := Max( ::nRow - 1, 1 )
      nTo   := 1
      nStep := -1
   ENDCASE

   FOR nFor := nFrom TO nTo STEP nStep
      IF cString $ iif( lCaseSensitive, ::GetLine( nFor ), Upper( ::GetLine( nFor ) ) )
         lFound := .T.
         ::GotoLine( nFor )
         EXIT
      ENDIF
   NEXT

   RETURN lFound
tbrwtext.prg254

Page url: http://www.yourdomain.com/help/index.html?debug.htm