diff options
Diffstat (limited to 'src/ccInstHelper.cpp')
-rw-r--r-- | src/ccInstHelper.cpp | 334 |
1 files changed, 334 insertions, 0 deletions
diff --git a/src/ccInstHelper.cpp b/src/ccInstHelper.cpp new file mode 100644 index 0000000..055e2d6 --- /dev/null +++ b/src/ccInstHelper.cpp @@ -0,0 +1,334 @@ +// uninstallHelper.cpp : Defines the entry point for the console application. +// +#include <iostream> +#include <string> +#include <vector> +#include <list> +#include <windows.h> +#include <string.h> +#include <io.h> + +//#define __stdcall + +#ifndef KREPLACEMENTS_H +// For compilation download the NSIS source package and modify the following +// line to point to the exdll.h-file +#include "C:/Programme/NSIS/Contrib/ExDll/exdll.h" +#endif + +struct ReplacementItem +{ char* fileType; char* operationType; }; + +ReplacementItem g_replacementTable[] = { + "text_file_delta", "xcompare", + "text_file_delta", "xmerge", + "whole_copy", "xcompare", + "whole_copy", "xmerge", + "z_text_file_delta", "xcompare", + "z_text_file_delta", "xmerge", + "z_whole_copy", "xcompare", + "z_whole_copy", "xmerge", + "_xml", "xcompare", + "_xml", "xmerge", + "_xml2", "xcompare", + "_xml2", "xmerge", + "_rftdef", "xcompare", + "_rftmap", "xcompare", + "_rftvp", "xcompare", + "_xtools", "xcompare", + 0,0 +}; + +struct LineItem +{ + std::string fileType; + std::string opType; + std::string command; + std::string fileOpPart; +}; + +// Return true if successful, else false +bool readAndParseMapFile( const std::string& filename, std::list<LineItem>& lineItemList ) +{ + // Read file + FILE* pFile = fopen( filename.c_str(), "r" ); + if (pFile) + { + fseek(pFile,0,SEEK_END); + int size = ftell(pFile); + fseek(pFile,0,SEEK_SET); + std::vector<char> buf( size ); + fread( &buf[0], 1, size, pFile ); + fclose( pFile ); + + // Replace strings + int lineStartPos=0; + int wordInLine = 0; + LineItem lineItem; + for( int i=0; i<size; ) + { + if( buf[i] == '\n' || buf[i] == '\r' ) + { + ++i; + wordInLine = 0; + lineStartPos = i; + continue; + } + if( buf[i] == ' ' || buf[i] == '\t' ) + { + ++i; + continue; + } + else + { + int wordStartPos = i; + if (wordInLine<2) + { + while ( i<size && !( buf[i] == ' ' || buf[i] == '\t' ) ) + ++i; + + std::string word( &buf[wordStartPos], i-wordStartPos ); + if (wordInLine==0) + lineItem.fileType = word; + else + lineItem.opType = word; + ++wordInLine; + } + else + { + lineItem.fileOpPart = std::string( &buf[lineStartPos], i-lineStartPos ); + while ( i<size && !( buf[i] == '\n' || buf[i] == '\r' ) ) + ++i; + + std::string word( &buf[wordStartPos], i-wordStartPos ); + lineItem.command = word; + lineItemList.push_back( lineItem ); + } + } + } + } + else + { + return false; + } + return true; +} + +bool writeMapFile( const std::string& filename, const std::list<LineItem>& lineItemList ) +{ + FILE* pFile = fopen( filename.c_str(), "w" ); + if (pFile) + { + std::list<LineItem>::const_iterator i = lineItemList.begin(); + for( ; i!=lineItemList.end(); ++i ) + { + const LineItem& li = *i; + fprintf( pFile, "%s%s\n", li.fileOpPart.c_str(), li.command.c_str() ); + } + fclose( pFile ); + } + else + { + return false; + } + return true; +} + +std::string toUpper( const std::string& s ) +{ + std::string s2 = s; + + for( unsigned int i=0; i<s.length(); ++i ) + { + s2[i] = toupper( s2[i] ); + } + return s2; +} + +int integrateWithClearCase( const char* subCommand, const char* kdiff3CommandPath ) +{ + std::string installCommand = subCommand; // "install" or "uninstall" or "existsClearCase" + std::string kdiff3Command = kdiff3CommandPath; + + /* + std::wstring installCommand = subCommand; // "install" or "uninstall" + std::wstring wKDiff3Command = kdiff3CommandPath; + std::string kdiff3Command; + kdiff3Command.reserve( wKDiff3Command.length()+1 ); + kdiff3Command.resize( wKDiff3Command.length() ); + BOOL bUsedDefaultChar = FALSE; + int successLen = WideCharToMultiByte( CP_ACP, 0, + wKDiff3Command.c_str(), int(wKDiff3Command.length()), + &kdiff3Command[0], int(kdiff3Command.length()), 0, &bUsedDefaultChar ); + + if ( successLen != kdiff3Command.length() || bUsedDefaultChar ) + { + std::cerr << "KDiff3 command contains characters that don't map to ansi code page.\n" + "Aborting clearcase installation.\n" + "Try to install KDiff3 in another path that doesn't require special characters.\n"; + return -1; + } + */ + + // Try to locate cleartool, the clearcase tool in the path + char buffer[1000]; + char* pLastPart = 0; + int len = SearchPathA(0, "cleartool.exe", 0, sizeof(buffer)/sizeof(buffer[0]), + buffer, &pLastPart ); + if ( len>0 && len+1<int(sizeof(buffer)/sizeof(buffer[0])) && pLastPart ) + { + pLastPart[-1] = 0; + pLastPart = strrchr( buffer, '\\' ); // cd up (because cleartool.exe is in bin subdir) + if ( pLastPart ) + pLastPart[1]=0; + + std::string path( buffer ); + path += "lib\\mgrs\\map"; + std::string bakName = path + ".preKDiff3Install"; + + if ( installCommand == "existsClearCase") + { + return 1; + } + else if ( installCommand == "install") + { + std::list<LineItem> lineItemList; + bool bSuccess = readAndParseMapFile( path, lineItemList ); + if ( !bSuccess ) + { + std::cerr << "Error reading original map file.\n"; + return -1; + } + + // Create backup + if ( access( bakName.c_str(), 0 )!=0 ) // Create backup only if not exists yet + { + if ( rename( path.c_str(), bakName.c_str() ) ) + { + std::cerr << "Error renaming original map file.\n"; + return -1; + } + } + + std::list<LineItem>::iterator i = lineItemList.begin(); + for( ; i!=lineItemList.end(); ++i ) + { + LineItem& li = *i; + for (int j=0;;++j) + { + ReplacementItem& ri = g_replacementTable[j]; + if ( ri.fileType==0 || ri.operationType==0 ) + break; + if ( li.fileType == ri.fileType && li.opType == ri.operationType ) + { + li.command = kdiff3Command.c_str(); + break; + } + } + } + + bSuccess = writeMapFile( path, lineItemList ); + if ( !bSuccess ) + { + if ( rename( bakName.c_str(), path.c_str() ) ) + std::cerr << "Error writing new map file, restoring old file also failed.\n"; + else + std::cerr << "Error writing new map file, old file restored.\n"; + + return -1; + } + } + else if ( installCommand == "uninstall" ) + { + std::list<LineItem> lineItemList; + bool bSuccess = readAndParseMapFile( path, lineItemList ); + if ( !bSuccess ) + { + std::cerr << "Error reading original map file\n."; + return -1; + } + + std::list<LineItem> lineItemListBak; + bSuccess = readAndParseMapFile( bakName, lineItemListBak ); + if ( !bSuccess ) + { + std::cerr << "Error reading backup map file.\n"; + return -1; + } + + std::list<LineItem>::iterator i = lineItemList.begin(); + for( ; i!=lineItemList.end(); ++i ) + { + LineItem& li = *i; + if ((int)toUpper(li.command).find("KDIFF3")>=0) + { + std::list<LineItem>::const_iterator j = lineItemListBak.begin(); + for (;j!=lineItemListBak.end();++j) + { + const LineItem& bi = *j; // backup iterator + if ( li.fileType == bi.fileType && li.opType == bi.opType ) + { + li.command = bi.command; + break; + } + } + } + } + + bSuccess = writeMapFile( path, lineItemList ); + if ( !bSuccess ) + { + std::cerr << "Error writing map file."; + + return -1; + } + } + } + return 0; +} + +#ifndef KREPLACEMENTS_H + +extern "C" +void __declspec(dllexport) nsisPlugin(HWND hwndParent, int string_size, + char *variables, stack_t **stacktop, + extra_parameters *extra) +{ + //g_hwndParent=hwndParent; + + EXDLL_INIT(); + { + std::string param1( g_stringsize, ' ' ); + int retVal = popstring( ¶m1[0] ); + if ( retVal == 0 ) + { + std::string param2( g_stringsize, ' ' ); + retVal = popstring( ¶m2[0] ); + if ( retVal == 0 ) + install( param1.c_str(), param2.c_str() ); + return; + } + std::cerr << "Not enough parameters." << std::endl; + } +} + +#endif +/* +int _tmain(int argc, _TCHAR* argv[]) +{ + if ( argc<3 ) + { + std::cout << "This program is needed to install/uninstall KDiff3 for clearcase.\n" + "It tries to patch the map file (clearcase-subdir\\lib\\mgrs\\map)\n" + "Usage 1: ccInstHelper install pathToKdiff3.exe\n" + "Usage 2: ccInstHelper uninstall pathToKdiff3.exe\n" + "Backups of the original map files are created in the dir of the map file.\n"; + } + else + { + return install( argv[1], argv[2] ); + } + + return 0; +} +*/ |