CHistoryItem::CHistoryItem( const CHistoryItem& src ) { m_text = NULL; m_extraText = NULL; m_bHasExtra = false; SetText( src.GetText(), src.GetExtra() ); }
void CConsolePanel::AddToHistory( const char *commandText, const char *extraText ) { // Newest at end, oldest at head while ( m_CommandHistory.Count() >= MAX_HISTORY_ITEMS ) { // Remove from head until size is reasonable m_CommandHistory.Remove( 0 ); } // strip the space off the end of the command before adding it to the history // If this code gets cleaned up then we should remove the redundant calls to strlen, // the check for whether _alloca succeeded, and should use V_strncpy instead of the // error prone memset/strncpy sequence. char *command = static_cast<char *>( _alloca( (strlen( commandText ) + 1 ) * sizeof( char ) )); if ( command ) { memset( command, 0x0, strlen( commandText ) + 1 ); strncpy( command, commandText, strlen( commandText )); // There is no actual bug here, just some sloppy/odd code. // src\vgui2\vgui_controls\consoledialog.cpp(974): warning C6053: The prior call to 'strncpy' might not zero-terminate string 'command' ANALYZE_SUPPRESS( 6053 ) if ( command[ strlen( command ) -1 ] == ' ' ) { command[ strlen( command ) -1 ] = '\0'; } } // strip the quotes off the extra text char *extra = NULL; if ( extraText ) { extra = static_cast<char *>( malloc( (strlen( extraText ) + 1 ) * sizeof( char ) )); if ( extra ) { memset( extra, 0x0, strlen( extraText ) + 1 ); strncpy( extra, extraText, strlen( extraText )); // +1 to dodge the starting quote // Strip trailing spaces int i = strlen( extra ) - 1; while ( i >= 0 && // Check I before referencing i == -1 into the extra array! extra[ i ] == ' ' ) { extra[ i ] = '\0'; i--; } } } // If it's already there, then remove since we'll add it to the end instead CHistoryItem *item = NULL; for ( int i = m_CommandHistory.Count() - 1; i >= 0; i-- ) { item = &m_CommandHistory[ i ]; if ( !item ) continue; if ( stricmp( item->GetText(), command ) ) continue; if ( extra || item->GetExtra() ) { if ( !extra || !item->GetExtra() ) continue; // stricmp so two commands with the same starting text get added if ( stricmp( item->GetExtra(), extra ) ) continue; } m_CommandHistory.Remove( i ); } item = &m_CommandHistory[ m_CommandHistory.AddToTail() ]; Assert( item ); item->SetText( command, extra ); m_iNextCompletion = 0; RebuildCompletionList( m_szPartialText ); free( extra ); }
void CConsolePanel::AddToHistory( const char *commandText, const char *extraText ) { while ( m_CommandHistory.Count() >= MAX_HISTORY_ITEMS ) { m_CommandHistory.Remove( 0 ); } char *command = static_cast<char *>( _alloca( (strlen( commandText ) + 1 ) * sizeof( char ) )); if ( command ) { memset( command, 0x0, strlen( commandText ) + 1 ); strncpy( command, commandText, strlen( commandText )); if ( command[ strlen( command ) -1 ] == ' ' ) { command[ strlen( command ) -1 ] = '\0'; } } char *extra = NULL; if ( extraText ) { extra = static_cast<char *>( malloc( (strlen( extraText ) + 1 ) * sizeof( char ) )); if ( extra ) { memset( extra, 0x0, strlen( extraText ) + 1 ); strncpy( extra, extraText, strlen( extraText )); int i = strlen( extra ) - 1; while ( i >= 0 && extra[ i ] == ' ' ) { extra[ i ] = '\0'; i--; } } } CHistoryItem *item = NULL; for ( int i = m_CommandHistory.Count() - 1; i >= 0; i-- ) { item = &m_CommandHistory[ i ]; if ( !item ) continue; if ( stricmp( item->GetText(), command ) ) continue; if ( extra || item->GetExtra() ) { if ( !extra || !item->GetExtra() ) continue; if ( stricmp( item->GetExtra(), extra ) ) continue; } m_CommandHistory.Remove( i ); } item = &m_CommandHistory[ m_CommandHistory.AddToTail() ]; Assert( item ); item->SetText( command, extra ); m_iNextCompletion = 0; RebuildCompletionList( m_szPartialText ); free( extra ); }