annotate kdiff3/windows_installer/ccinstallhelper/ccInstHelper.cpp @ 113:7bca1f1340f6 tip

Build fixes for Xcode 10 / Qt 5.12
author Chris Cannam
date Mon, 17 Dec 2018 11:13:01 +0000
parents 1184fc843210
children
rev   line source
joachim99@77 1 // uninstallHelper.cpp : Defines the entry point for the console application.
joachim99@77 2 //
joachim99@77 3 #define _CRT_SECURE_NO_DEPRECATE
joachim99@77 4 #include "stdafx.h"
joachim99@77 5 #include <iostream>
joachim99@77 6 #include <string>
joachim99@77 7 #include <vector>
joachim99@77 8 #include <list>
joachim99@77 9 #include <windows.h>
joachim99@77 10 #include <string.h>
joachim99@77 11 #include <io.h>
joachim99@77 12
joachim99@77 13 //#define __stdcall
joachim99@77 14
joachim99@77 15 // For compilation download the NSIS source package and modify the following
joachim99@77 16 // line to point to the exdll.h-file
joachim99@77 17 #include "C:/Programme/NSIS/Contrib/ExDll/exdll.h"
joachim99@77 18
joachim99@77 19 struct ReplacementItem
joachim99@77 20 { char* fileType; char* operationType; };
joachim99@77 21
joachim99@77 22 ReplacementItem g_replacementTable[] = {
joachim99@77 23 "text_file_delta", "xcompare",
joachim99@77 24 "text_file_delta", "xmerge",
joachim99@77 25 "whole_copy", "xcompare",
joachim99@77 26 "whole_copy", "xmerge",
joachim99@77 27 "z_text_file_delta", "xcompare",
joachim99@77 28 "z_text_file_delta", "xmerge",
joachim99@77 29 "z_whole_copy", "xcompare",
joachim99@77 30 "z_whole_copy", "xmerge",
joachim99@77 31 "_xml", "xcompare",
joachim99@77 32 "_xml", "xmerge",
joachim99@77 33 "_xml2", "xcompare",
joachim99@77 34 "_xml2", "xmerge",
joachim99@77 35 "_rftdef", "xcompare",
joachim99@77 36 "_rftmap", "xcompare",
joachim99@77 37 "_rftvp", "xcompare",
joachim99@77 38 "_xtools", "xcompare",
joachim99@77 39 0,0
joachim99@77 40 };
joachim99@77 41
joachim99@77 42 struct LineItem
joachim99@77 43 {
joachim99@77 44 std::string fileType;
joachim99@77 45 std::string opType;
joachim99@77 46 std::string command;
joachim99@77 47 std::string fileOpPart;
joachim99@77 48 };
joachim99@77 49
joachim99@77 50 // Return true if successful, else false
joachim99@77 51 bool readAndParseMapFile( const std::string& filename, std::list<LineItem>& lineItemList )
joachim99@77 52 {
joachim99@77 53 // Read file
joachim99@77 54 FILE* pFile = fopen( filename.c_str(), "r" );
joachim99@77 55 if (pFile)
joachim99@77 56 {
joachim99@77 57 fseek(pFile,0,SEEK_END);
joachim99@77 58 int size = ftell(pFile);
joachim99@77 59 fseek(pFile,0,SEEK_SET);
joachim99@77 60 std::vector<char> buf( size );
joachim99@77 61 fread( &buf[0], 1, size, pFile );
joachim99@77 62 fclose( pFile );
joachim99@77 63
joachim99@77 64 // Replace strings
joachim99@77 65 int lineStartPos=0;
joachim99@77 66 int wordInLine = 0;
joachim99@77 67 LineItem lineItem;
joachim99@77 68 for( int i=0; i<size; )
joachim99@77 69 {
joachim99@77 70 if( buf[i] == '\n' || buf[i] == '\r' )
joachim99@77 71 {
joachim99@77 72 ++i;
joachim99@77 73 wordInLine = 0;
joachim99@77 74 lineStartPos = i;
joachim99@77 75 continue;
joachim99@77 76 }
joachim99@77 77 if( buf[i] == ' ' || buf[i] == '\t' )
joachim99@77 78 {
joachim99@77 79 ++i;
joachim99@77 80 continue;
joachim99@77 81 }
joachim99@77 82 else
joachim99@77 83 {
joachim99@77 84 int wordStartPos = i;
joachim99@77 85 if (wordInLine<2)
joachim99@77 86 {
joachim99@77 87 while ( i<size && !( buf[i] == ' ' || buf[i] == '\t' ) )
joachim99@77 88 ++i;
joachim99@77 89
joachim99@77 90 std::string word( &buf[wordStartPos], i-wordStartPos );
joachim99@77 91 if (wordInLine==0)
joachim99@77 92 lineItem.fileType = word;
joachim99@77 93 else
joachim99@77 94 lineItem.opType = word;
joachim99@77 95 ++wordInLine;
joachim99@77 96 }
joachim99@77 97 else
joachim99@77 98 {
joachim99@77 99 lineItem.fileOpPart = std::string( &buf[lineStartPos], i-lineStartPos );
joachim99@77 100 while ( i<size && !( buf[i] == '\n' || buf[i] == '\r' ) )
joachim99@77 101 ++i;
joachim99@77 102
joachim99@77 103 std::string word( &buf[wordStartPos], i-wordStartPos );
joachim99@77 104 lineItem.command = word;
joachim99@77 105 lineItemList.push_back( lineItem );
joachim99@77 106 }
joachim99@77 107 }
joachim99@77 108 }
joachim99@77 109 }
joachim99@77 110 else
joachim99@77 111 {
joachim99@77 112 return false;
joachim99@77 113 }
joachim99@77 114 return true;
joachim99@77 115 }
joachim99@77 116
joachim99@77 117 bool writeMapFile( const std::string& filename, const std::list<LineItem>& lineItemList )
joachim99@77 118 {
joachim99@77 119 FILE* pFile = fopen( filename.c_str(), "w" );
joachim99@77 120 if (pFile)
joachim99@77 121 {
joachim99@77 122 std::list<LineItem>::const_iterator i = lineItemList.begin();
joachim99@77 123 for( ; i!=lineItemList.end(); ++i )
joachim99@77 124 {
joachim99@77 125 const LineItem& li = *i;
joachim99@77 126 fprintf( pFile, "%s%s\n", li.fileOpPart.c_str(), li.command.c_str() );
joachim99@77 127 }
joachim99@77 128 fclose( pFile );
joachim99@77 129 }
joachim99@77 130 else
joachim99@77 131 {
joachim99@77 132 return false;
joachim99@77 133 }
joachim99@77 134 return true;
joachim99@77 135 }
joachim99@77 136
joachim99@77 137 std::string toUpper( const std::string& s )
joachim99@77 138 {
joachim99@77 139 std::string s2 = s;
joachim99@77 140
joachim99@77 141 for( unsigned int i=0; i<s.length(); ++i )
joachim99@77 142 {
joachim99@77 143 s2[i] = toupper( s2[i] );
joachim99@77 144 }
joachim99@77 145 return s2;
joachim99@77 146 }
joachim99@77 147
joachim99@77 148 int install( const _TCHAR* subCommand, const _TCHAR* kdiff3CommandPath )
joachim99@77 149 {
joachim99@77 150 std::string installCommand = subCommand; // "install" or "uninstall"
joachim99@77 151 std::string kdiff3Command = kdiff3CommandPath;
joachim99@77 152
joachim99@77 153 /*
joachim99@77 154 std::wstring installCommand = subCommand; // "install" or "uninstall"
joachim99@77 155 std::wstring wKDiff3Command = kdiff3CommandPath;
joachim99@77 156 std::string kdiff3Command;
joachim99@77 157 kdiff3Command.reserve( wKDiff3Command.length()+1 );
joachim99@77 158 kdiff3Command.resize( wKDiff3Command.length() );
joachim99@77 159 BOOL bUsedDefaultChar = FALSE;
joachim99@77 160 int successLen = WideCharToMultiByte( CP_ACP, 0,
joachim99@77 161 wKDiff3Command.c_str(), int(wKDiff3Command.length()),
joachim99@77 162 &kdiff3Command[0], int(kdiff3Command.length()), 0, &bUsedDefaultChar );
joachim99@77 163
joachim99@77 164 if ( successLen != kdiff3Command.length() || bUsedDefaultChar )
joachim99@77 165 {
joachim99@77 166 std::cerr << "KDiff3 command contains characters that don't map to ansi code page.\n"
joachim99@77 167 "Aborting clearcase installation.\n"
joachim99@77 168 "Try to install KDiff3 in another path that doesn't require special characters.\n";
joachim99@77 169 return -1;
joachim99@77 170 }
joachim99@77 171 */
joachim99@77 172
joachim99@77 173 // Try to locate cleartool, the clearcase tool in the path
joachim99@77 174 char buffer[1000];
joachim99@77 175 char* pLastPart = 0;
joachim99@77 176 int len = SearchPathA(0, "cleartool.exe", 0, sizeof(buffer)/sizeof(buffer[0]),
joachim99@77 177 buffer, &pLastPart );
joachim99@77 178 if ( len+1<int(sizeof(buffer)/sizeof(buffer[0])) && pLastPart )
joachim99@77 179 {
joachim99@77 180 pLastPart[-1] = 0;
joachim99@77 181 pLastPart = strchr( buffer, '\\' ); // cd up (because cleartool.exe is in bin subdir)
joachim99@77 182 if ( pLastPart )
joachim99@77 183 pLastPart[1]=0;
joachim99@77 184
joachim99@77 185 std::string path( buffer );
joachim99@77 186 path += _T("lib\\mgrs\\map");
joachim99@77 187 std::string bakName = path + _T(".preKDiff3Install");
joachim99@77 188
joachim99@77 189 if ( installCommand == _T("install") )
joachim99@77 190 {
joachim99@77 191 std::list<LineItem> lineItemList;
joachim99@77 192 bool bSuccess = readAndParseMapFile( path, lineItemList );
joachim99@77 193 if ( !bSuccess )
joachim99@77 194 {
joachim99@77 195 std::cerr << "Error reading original map file.\n";
joachim99@77 196 return -1;
joachim99@77 197 }
joachim99@77 198
joachim99@77 199 // Create backup
joachim99@77 200 if ( access( bakName.c_str(), 0 )!=0 ) // Create backup only if not exists yet
joachim99@77 201 {
joachim99@77 202 if ( rename( path.c_str(), bakName.c_str() ) )
joachim99@77 203 {
joachim99@77 204 std::cerr << "Error renaming original map file.\n";
joachim99@77 205 return -1;
joachim99@77 206 }
joachim99@77 207 }
joachim99@77 208
joachim99@77 209 std::list<LineItem>::iterator i = lineItemList.begin();
joachim99@77 210 for( ; i!=lineItemList.end(); ++i )
joachim99@77 211 {
joachim99@77 212 LineItem& li = *i;
joachim99@77 213 for (int j=0;;++j)
joachim99@77 214 {
joachim99@77 215 ReplacementItem& ri = g_replacementTable[j];
joachim99@77 216 if ( ri.fileType==0 || ri.operationType==0 )
joachim99@77 217 break;
joachim99@77 218 if ( li.fileType == ri.fileType && li.opType == ri.operationType )
joachim99@77 219 {
joachim99@77 220 li.command = kdiff3Command.c_str();
joachim99@77 221 break;
joachim99@77 222 }
joachim99@77 223 }
joachim99@77 224 }
joachim99@77 225
joachim99@77 226 bSuccess = writeMapFile( path, lineItemList );
joachim99@77 227 if ( !bSuccess )
joachim99@77 228 {
joachim99@77 229 if ( rename( bakName.c_str(), path.c_str() ) )
joachim99@77 230 std::cerr << "Error writing new map file, restoring old file also failed.\n";
joachim99@77 231 else
joachim99@77 232 std::cerr << "Error writing new map file, old file restored.\n";
joachim99@77 233
joachim99@77 234 return -1;
joachim99@77 235 }
joachim99@77 236 }
joachim99@77 237 else if ( installCommand == _T("uninstall") )
joachim99@77 238 {
joachim99@77 239 std::list<LineItem> lineItemList;
joachim99@77 240 bool bSuccess = readAndParseMapFile( path, lineItemList );
joachim99@77 241 if ( !bSuccess )
joachim99@77 242 {
joachim99@77 243 std::cerr << "Error reading original map file\n.";
joachim99@77 244 return -1;
joachim99@77 245 }
joachim99@77 246
joachim99@77 247 std::list<LineItem> lineItemListBak;
joachim99@77 248 bSuccess = readAndParseMapFile( bakName, lineItemListBak );
joachim99@77 249 if ( !bSuccess )
joachim99@77 250 {
joachim99@77 251 std::cerr << "Error reading backup map file.\n";
joachim99@77 252 return -1;
joachim99@77 253 }
joachim99@77 254
joachim99@77 255 std::list<LineItem>::iterator i = lineItemList.begin();
joachim99@77 256 for( ; i!=lineItemList.end(); ++i )
joachim99@77 257 {
joachim99@77 258 LineItem& li = *i;
joachim99@77 259 if ((int)toUpper(li.command).find("KDIFF3")>=0)
joachim99@77 260 {
joachim99@77 261 std::list<LineItem>::const_iterator j = lineItemListBak.begin();
joachim99@77 262 for (;j!=lineItemListBak.end();++j)
joachim99@77 263 {
joachim99@77 264 const LineItem& bi = *j; // backup iterator
joachim99@77 265 if ( li.fileType == bi.fileType && li.opType == bi.opType )
joachim99@77 266 {
joachim99@77 267 li.command = bi.command;
joachim99@77 268 break;
joachim99@77 269 }
joachim99@77 270 }
joachim99@77 271 }
joachim99@77 272 }
joachim99@77 273
joachim99@77 274 bSuccess = writeMapFile( path, lineItemList );
joachim99@77 275 if ( !bSuccess )
joachim99@77 276 {
joachim99@77 277 std::cerr << "Error writing map file.";
joachim99@77 278
joachim99@77 279 return -1;
joachim99@77 280 }
joachim99@77 281 }
joachim99@77 282 }
joachim99@77 283 return 0;
joachim99@77 284 }
joachim99@77 285
joachim99@77 286 extern "C"
joachim99@77 287 void __declspec(dllexport) nsisPlugin(HWND hwndParent, int string_size,
joachim99@77 288 char *variables, stack_t **stacktop,
joachim99@77 289 extra_parameters *extra)
joachim99@77 290 {
joachim99@77 291 //g_hwndParent=hwndParent;
joachim99@77 292
joachim99@77 293 EXDLL_INIT();
joachim99@77 294 {
joachim99@77 295 std::string param1( g_stringsize, ' ' );
joachim99@77 296 int retVal = popstring( &param1[0] );
joachim99@77 297 if ( retVal == 0 )
joachim99@77 298 {
joachim99@77 299 std::string param2( g_stringsize, ' ' );
joachim99@77 300 retVal = popstring( &param2[0] );
joachim99@77 301 if ( retVal == 0 )
joachim99@77 302 install( param1.c_str(), param2.c_str() );
joachim99@77 303 return;
joachim99@77 304 }
joachim99@77 305 std::cerr << "Not enough parameters." << std::endl;
joachim99@77 306 }
joachim99@77 307 }
joachim99@77 308
joachim99@77 309 /*
joachim99@77 310 int _tmain(int argc, _TCHAR* argv[])
joachim99@77 311 {
joachim99@77 312 if ( argc<3 )
joachim99@77 313 {
joachim99@77 314 std::cout << "This program is needed to install/uninstall KDiff3 for clearcase.\n"
joachim99@77 315 "It tries to patch the map file (clearcase-subdir\\lib\\mgrs\\map)\n"
joachim99@77 316 "Usage 1: ccInstHelper install pathToKdiff3.exe\n"
joachim99@77 317 "Usage 2: ccInstHelper uninstall pathToKdiff3.exe\n"
joachim99@77 318 "Backups of the original map files are created in the dir of the map file.\n";
joachim99@77 319 }
joachim99@77 320 else
joachim99@77 321 {
joachim99@77 322 return install( argv[1], argv[2] );
joachim99@77 323 }
joachim99@77 324
joachim99@77 325 return 0;
joachim99@77 326 }
joachim99@77 327 */