summaryrefslogblamecommitdiffstats
path: root/tools/SearchReplace/SearchReplace.cpp
blob: f2fe3a9a2abd36e7317566b0edb84588a2f20a56 (plain) (tree)















































































































































































































































































































































                                                                                                
// SearchReplace.cpp : Defines the entry point for the console application.
//

#include <assert.h>
#include <vector>

class ReplacementTableEntry;

std::vector<ReplacementTableEntry*> gReplacementTable;

bool BuildReplacementTable( FILE* rulesFile );
void RemoveNewLine( char* string );
bool IsWhiteSpace( char* string );
void ProcessSourceFile( FILE* sourceFile, FILE* targetFile );



class ReplacementTableEntry
{
    public:

        ReplacementTableEntry( const char* findString, const char* replaceString );
        ~ReplacementTableEntry();
    
        char* mFindString;
        char* mReplaceString;
};


ReplacementTableEntry::ReplacementTableEntry
( 
    const char* findString, 
    const char* replaceString
)
:
mFindString( 0 ),
mReplaceString( 0 )
{
    assert( findString );
    assert( replaceString );

    mFindString = new char[strlen(findString)+1];
    strcpy( mFindString, findString );

    mReplaceString = new char[strlen(replaceString)+1];
    strcpy( mReplaceString, replaceString );
}

ReplacementTableEntry::~ReplacementTableEntry()
{
    delete [] mFindString;
    delete [] mReplaceString;
}



//==============================================================================
// int main
//==============================================================================
//
// Description: 
//
// Parameters:  
//
// Return:      
//
//==============================================================================
int main(int argc, char* argv[])
{
	// Validate command line arguments
    assert( argc == 4 );

    const char* rulesName = argv[1];
    const char* sourceName = argv[2];
    const char* targetName = argv[3];

    // Open rules file
    FILE* rulesFile = fopen( rulesName, "rt" );

    if( rulesFile == NULL )
    {
        printf( "Failed to open rules file: %s\n", rulesName );
        return( 0 );
    }

    // Build search and replace table
    bool result = BuildReplacementTable( rulesFile );

    // Close rules file
    fclose( rulesFile );


    // Open source file
    FILE* sourceFile = fopen( sourceName, "rt" );

    if( sourceFile == NULL )
    {
        fclose( rulesFile );
        printf( "Failed to open source file: %s\n", sourceName );
        return( 0 );
    }

    // Open target file
    FILE* targetFile = fopen( targetName, "wt" );

    if( targetFile == NULL )
    {
        fclose( rulesFile );
        fclose( sourceFile );
        printf( "Failed to open target file: %s\n", targetName );
        return( 0 );
    }
    
    // Process source file

    ProcessSourceFile( sourceFile, targetFile );

    fclose( sourceFile );
    fclose( targetFile );
      
  
    // Clean up
    std::vector<ReplacementTableEntry*>::const_iterator iter = gReplacementTable.begin();

    for( ; iter != gReplacementTable.end(); ++iter )
    {
        ReplacementTableEntry* entry = (*iter);
        
        delete entry;
    }

    gReplacementTable.clear();
  
	return 0;
}


//==============================================================================
// bool BuildReplacementTable
//==============================================================================
//
// Description: 
//
// Parameters:  
//
// Return:      
//
//==============================================================================
bool BuildReplacementTable( FILE* rulesFile )
{
    // Get the next line from the file

    int lineCount = 0;

    while( 1 )
    {
        const int BUFFER_SIZE = 512;
        char* fgetsResult;
        char lineBuffer[BUFFER_SIZE];
        
        do
        {   if( feof( rulesFile ) )
            {
                return( true );
            }
            
            fgetsResult = fgets( lineBuffer, BUFFER_SIZE, rulesFile );
            ++lineCount;
        }
        while( IsWhiteSpace( lineBuffer ) == true );

        char findString[BUFFER_SIZE];
        strcpy( findString, lineBuffer );
        RemoveNewLine( findString );
        

        do
        {
            if( feof( rulesFile ) )
            {
                printf( "Error in rules file, missing replace string (line: %d)\n", lineCount );
                return( false );
            }

            fgetsResult = fgets( lineBuffer, BUFFER_SIZE, rulesFile );
            ++lineCount;
        }
        while( IsWhiteSpace( lineBuffer ) == true );

        char replaceString[BUFFER_SIZE];
        strcpy( replaceString, lineBuffer );
        RemoveNewLine( replaceString );
        
        // Create Entry
        //
        ReplacementTableEntry* entry = new ReplacementTableEntry( findString, replaceString );
        gReplacementTable.push_back( entry );
    }
}


//==============================================================================
// void RemoveNewLine
//==============================================================================
//
// Description: 
//
// Parameters:  
//
// Return:      
//
//==============================================================================
void RemoveNewLine( char* string )
{
    assert( string );
    
    int length = strlen( string );
    
    int i;
    for( i = 0; i < length; ++i )
    {
        if( '\n' == string[i] )
        {
            string[i] = '\0';
        }
    }
}


//==============================================================================
// bool IsWhiteSpace
//==============================================================================
//
// Description: 
//
// Parameters:  
//
// Return:      
//
//==============================================================================
bool IsWhiteSpace( char* string )
{
    assert( string );
    
    int length = strlen( string );
    
    int i;
    for( i = 0; i < length; ++i )
    {
        if( (string[i] != '\n') && (string[i] != ' ') )
        {
            return( false );
        }
    }

    return( true );
}


//==============================================================================
// void ProcessSourceFile
//==============================================================================
//
// Description: 
//
// Parameters:  
//
// Return:      
//
//==============================================================================
void ProcessSourceFile( FILE* sourceFile, FILE* targetFile )
{
    int lineNumber = 0;
    while( !feof( sourceFile ) )
    {
        // Read in a line from the source
        const int BUFFER_SIZE = 1024;
        char* fgetsResult;
        char sourceBuffer[BUFFER_SIZE];
        char targetBuffer[BUFFER_SIZE];
        
        fgetsResult = fgets( sourceBuffer, BUFFER_SIZE, sourceFile );
        strcpy( targetBuffer, sourceBuffer );
        ++lineNumber;

        // Iterate through the find strings for a match
        std::vector<ReplacementTableEntry*>::const_iterator iter = gReplacementTable.begin();

        for( ; iter != gReplacementTable.end(); ++iter )
        {
            ReplacementTableEntry* entry = (*iter);
        
            char* start = sourceBuffer;
            char* targetPos = targetBuffer;
            char* found = NULL;
            
            do
            {
                found = strstr( start, entry->mFindString );
        
                // Replace if found
                if( found != NULL )
                {
                    // Copy over the prefix
                    memcpy(targetPos, start, found - start );
                    targetPos += found - start;
                    
                    // Copy over the replacement string
                    memcpy(targetPos, entry->mReplaceString, strlen( entry->mReplaceString ) );
                    targetPos += strlen( entry->mReplaceString );
                    start = found + strlen( entry->mFindString );

                    // Copy over the postfix
                    memcpy( targetPos, start, strlen(start) );

                    // NULL terminate
                    char* term = targetPos + strlen(start);
                    *term = '\0';
                }
            }
            while( found != NULL );

            // The target now becomes the source to preserve any replacements.
            strcpy( sourceBuffer, targetBuffer );
        }

        // Write out line to target
        fputs( targetBuffer, targetFile );
    }
    

    
    

    
}