summaryrefslogtreecommitdiffstats
path: root/src/ccInstHelper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ccInstHelper.cpp')
-rw-r--r--src/ccInstHelper.cpp334
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( &param1[0] );
+ if ( retVal == 0 )
+ {
+ std::string param2( g_stringsize, ' ' );
+ retVal = popstring( &param2[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;
+}
+*/