int DoBdiff( const char *srcPath, const char *tgtPath, const char *name ) { long savings; foff buffsize; int i; // if( !MsgInit() ) exit( EXIT_FAILURE ); /* initialize static variables each time */ SimilarRegions = NULL; DiffRegions = NULL; HoleRegions = NULL; SimilarSize = 0; NumHoles = 0; NumDiffs = 0; DiffSize = 0; HolesInRegion = 0; HoleHeaders = 0; for( i = 0; i < 3; i += 1 ) { HoleCount[i] = 0; } init_diff(); newName = name; EndOld = FileSize( srcPath, &OldCorrection ); EndNew = FileSize( tgtPath, &NewCorrection ); buffsize = ( EndOld > EndNew ) ? ( EndOld ) : ( EndNew ); buffsize += sizeof( PATCH_LEVEL ); OldFile = ReadIn( srcPath, buffsize, EndOld ); NewFile = ReadIn( tgtPath, buffsize, EndNew ); ScanSyncString( SyncString ); FindRegions(); if( NumHoles == 0 && DiffSize == 0 && EndOld == EndNew ) { printf( "Patch file not created - files are identical\n" ); MsgFini(); exit( EXIT_SUCCESS ); } MakeHoleArray(); SortHoleArray(); ProcessHoleArray( 0 ); savings = HolesToDiffs(); WritePatchFile( "", newName ); FreeHoleArray(); VerifyCorrect( tgtPath ); print_stats( savings ); MsgFini(); return ( EXIT_SUCCESS ); }
void main( int argc, char **argv ) { long savings; foff buffsize; algorithm alg; if( !MsgInit() ) exit( EXIT_FAILURE ); alg = ParseArgs( argc, argv ); EndOld = FileSize( argv[1], &OldCorrection ); EndNew = FileSize( argv[2], &NewCorrection ); buffsize = ( EndOld > EndNew ) ? ( EndOld ) : ( EndNew ); buffsize += sizeof( PATCH_LEVEL ); OldFile = ReadIn( argv[1], buffsize, EndOld ); NewFile = ReadIn( argv[2], buffsize, EndNew ); ScanSyncString( SyncString ); switch( alg ) { case ALG_NOTHING: FindRegions(); break; #ifdef USE_DBGINFO case ALG_ONLY_NEW: case ALG_BOTH: SymbolicDiff( alg, argv[1], argv[2] ); break; #endif } if( NumHoles == 0 && DiffSize == 0 && EndOld == EndNew ) { printf( "Patch file not created - files are identical\n" ); MsgFini(); exit( EXIT_SUCCESS ); } MakeHoleArray(); SortHoleArray(); ProcessHoleArray( 0 ); savings = HolesToDiffs(); WritePatchFile( argv[3], newName ); FreeHoleArray(); VerifyCorrect( argv[2] ); print_stats( savings ); MsgFini(); exit( EXIT_SUCCESS ); }
/** * @brief Runs diff-engine. */ BOOL CDiffWrapper::RunFileDiff() { String filepath1(m_s1File); String filepath2(m_s2File); replace_char(&*filepath1.begin(), '/', '\\'); replace_char(&*filepath2.begin(), '/', '\\'); BOOL bRet = TRUE; String strFile1Temp(filepath1); String strFile2Temp(filepath2); m_options.SetToDiffUtils(); if (m_bUseDiffList) m_nDiffs = m_pDiffList->GetSize(); if (m_bPluginsEnabled) { // Do the preprocessing now, overwrite the temp files // NOTE: FileTransform_UCS2ToUTF8() may create new temp // files and return new names, those created temp files // are deleted in end of function. if (m_infoPrediffer->bToBeScanned) { // this can only fail if the data can not be saved back (no more // place on disk ???) What to do then ?? FileTransform_Prediffing(strFile1Temp, m_sToFindPrediffer.c_str(), m_infoPrediffer, m_bPathsAreTemp); } else { // This can fail if the prediffer has a problem if (FileTransform_Prediffing(strFile1Temp, *m_infoPrediffer, m_bPathsAreTemp) == FALSE) { // display a message box CString sError; LangFormatString2(sError, IDS_PREDIFFER_ERROR, strFile1Temp.c_str(), m_infoPrediffer->pluginName.c_str()); AfxMessageBox(sError, MB_OK | MB_ICONSTOP); // don't use any more this prediffer m_infoPrediffer->bToBeScanned = FALSE; m_infoPrediffer->pluginName.erase(); } } // We use the same plugin for both files, so it must be defined before // second file ASSERT(m_infoPrediffer->bToBeScanned == FALSE); if (FileTransform_Prediffing(strFile2Temp, *m_infoPrediffer, m_bPathsAreTemp) == FALSE) { // display a message box CString sError; LangFormatString2(sError, IDS_PREDIFFER_ERROR, strFile2Temp.c_str(), m_infoPrediffer->pluginName.c_str()); AfxMessageBox(sError, MB_OK | MB_ICONSTOP); // don't use any more this prediffer m_infoPrediffer->bToBeScanned = FALSE; m_infoPrediffer->pluginName.erase(); } } // Comparing UTF-8 files seems to require this conversion? // I'm still very confused about why, as what the functions // document doing is UCS2 to UTF-8 conversion, nothing else. // Something is wrong here. - Kimmo FileTransform_UCS2ToUTF8(strFile1Temp, m_bPathsAreTemp); FileTransform_UCS2ToUTF8(strFile2Temp, m_bPathsAreTemp); DiffFileData diffdata; diffdata.SetDisplayFilepaths(filepath1.c_str(), filepath2.c_str()); // store true names for diff utils patch file // This opens & fstats both files (if it succeeds) if (!diffdata.OpenFiles(strFile1Temp.c_str(), strFile2Temp.c_str())) { return FALSE; } // Compare the files, if no error was found. // Last param (bin_file) is NULL since we don't // (yet) need info about binary sides. int bin_flag = 0; struct change *script = NULL; bRet = Diff2Files(&script, &diffdata, &bin_flag, NULL); // We don't anymore create diff-files for every rescan. // User can create patch-file whenever one wants to. // We don't need to waste time. But lets keep this as // debugging aid. Sometimes it is very useful to see // what differences diff-engine sees! #ifdef _DEBUG // throw the diff into a temp file String sTempPath = env_GetTempPath(); // get path to Temp folder String path = paths_ConcatPath(sTempPath, _T("Diff.txt")); outfile = _tfopen(path.c_str(), _T("w+")); if (outfile != NULL) { print_normal_script(script); fclose(outfile); outfile = NULL; } #endif // First determine what happened during comparison // If there were errors or files were binaries, don't bother // creating diff-lists or patches // diff_2_files set bin_flag to -1 if different binary // diff_2_files set bin_flag to +1 if same binary if (bin_flag != 0) { m_status.bBinaries = TRUE; if (bin_flag == -1) m_status.bIdentical = FALSE; else m_status.bIdentical = TRUE; } else { // text files according to diffutils, so change script exists m_status.bIdentical = (script == 0); m_status.bBinaries = FALSE; } file_data * inf = diffdata.m_inf; m_status.bLeftMissingNL = inf[0].missing_newline; m_status.bRightMissingNL = inf[1].missing_newline; // Create patch file if (!m_status.bBinaries && m_bCreatePatchFile) { WritePatchFile(script, &inf[0]); } // Go through diffs adding them to WinMerge's diff list // This is done on every WinMerge's doc rescan! if (!m_status.bBinaries && m_bUseDiffList) { LoadWinMergeDiffsFromDiffUtilsScript(script, diffdata.m_inf); } FreeDiffUtilsScript(script); // Done with diffutils filedata diffdata.Close(); if (m_bPluginsEnabled) { // Delete temp files transformation functions possibly created if (lstrcmpi(filepath1.c_str(), strFile1Temp.c_str()) != 0) { if (!::DeleteFile(strFile1Temp.c_str())) { LogErrorString(Fmt(_T("DeleteFile(%s) failed: %s"), strFile1Temp.c_str(), GetSysError(GetLastError()).c_str())); } strFile1Temp.erase(); } if (lstrcmpi(filepath2.c_str(), strFile2Temp.c_str()) != 0) { if (!::DeleteFile(strFile2Temp.c_str())) { LogErrorString(Fmt(_T("DeleteFile(%s) failed: %s"), strFile2Temp.c_str(), GetSysError(GetLastError()).c_str())); } strFile2Temp.erase(); } } return bRet; }