Ejemplo n.º 1
0
/**
 * @brief Update file's modification time.
 * @param [in] info Contains filename, path and file times to update.
 */
void files_UpdateFileTime(const DiffFileInfo & info)
{
	String path = paths_ConcatPath(info.path, info.filename);
	_utimbuf times = {0};

	times.modtime = info.mtime;
	_tutime(path.c_str(), &times);
}
Ejemplo n.º 2
0
/** @brief Return path to right file, including all but file name */
String DIFFITEM::GetRightFilepath(const String &sRightRoot) const
{
	String sPath;
	if (!diffcode.isSideLeftOnly())
	{
		sPath = paths_ConcatPath(sRightRoot, right.path);
	}
	return sPath;
}
Ejemplo n.º 3
0
/** @brief Return path to left file, including all but file name */
String DIFFITEM::GetLeftFilepath(const String &sLeftRoot) const
{
	String sPath;
	if (!diffcode.isSideRightOnly())
	{
		sPath = paths_ConcatPath(sLeftRoot, left.path);
	}
	return sPath;
}
Ejemplo n.º 4
0
/**
 * @brief Install new filter.
 * This function is called when user selects "Install" button from GUI.
 * Function allows easy installation of new filters for user. For example
 * when user has downloaded filter file from net. First we ask user to
 * select filter to install. Then we copy selected filter to private
 * filters folder.
 */
void FileFiltersDlg::OnBnClickedFilterfileInstall()
{
    CString s;
    String path;
    String userPath = theApp.m_globalFileFilter.GetUserFilterPathWithCreate();

    if (SelectFile(GetSafeHwnd(), s, path.c_str(), IDS_FILEFILTER_INSTALL, IDS_FILEFILTER_FILEMASK,
                   TRUE))
    {
        String sfile, sext;
        SplitFilename(s, NULL, &sfile, &sext);
        String filename = sfile;
        filename += _T(".");
        filename += sext;
        userPath = paths_ConcatPath(userPath, filename);
        if (!CopyFile(s, userPath.c_str(), TRUE))
        {
            // If file already exists, ask from user
            // If user wants to, overwrite existing filter
            if (paths_DoesPathExist(userPath.c_str()) == IS_EXISTING_FILE)
            {
                int res = LangMessageBox(IDS_FILEFILTER_OVERWRITE, MB_YESNO |
                                         MB_ICONWARNING);
                if (res == IDYES)
                {
                    if (!CopyFile(s, userPath.c_str(), FALSE))
                    {
                        LangMessageBox(IDS_FILEFILTER_INSTALLFAIL, MB_ICONSTOP);
                    }
                }
            }
            else
            {
                LangMessageBox(IDS_FILEFILTER_INSTALLFAIL, MB_ICONSTOP);
            }
        }
        else
        {
            FileFilterMgr *pMgr = theApp.m_globalFileFilter.GetManager();
            pMgr->AddFilter(userPath.c_str());

            // Remove all from filterslist and re-add so we can update UI
            CString selected;
            m_Filters->RemoveAll();
            theApp.m_globalFileFilter.GetFileFilters(m_Filters, selected);

            UpdateFiltersList();
        }
    }
}
Ejemplo n.º 5
0
/**
 * @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;
}
Ejemplo n.º 6
0
/** 
 * @brief Write logfile
 */
bool CConfigLog::DoFile(bool writing, String &sError)
{
	CVersionInfo version;
	String text;

	m_writing = writing;

	if (writing)
	{
		String sFileName = paths_ConcatPath(env_GetMyDocuments(NULL), WinMergeDocumentsFolder);
		paths_CreateIfNeeded(sFileName.c_str());
		m_sFileName = paths_ConcatPath(sFileName, _T("WinMerge.txt"));

		if (!m_pfile->OpenCreateUtf8(m_sFileName.c_str()))
		{
			const UniFile::UniError &err = m_pfile->GetLastUniError();
			sError = err.GetError();
			return false;
		}
		m_pfile->SetBom(true);
		m_pfile->WriteBom();
	}

// Begin log
	FileWriteString(_T("WinMerge configuration log\r\n"));
	FileWriteString(_T("--------------------------\r\n"));
	FileWriteString(_T("Saved to: "));
	FileWriteString(m_sFileName.c_str());
	FileWriteString(_T("\r\n* Please add this information (or attach this file)\r\n"));
	FileWriteString(_T("* when reporting bugs.\r\n"));
	FileWriteString(_T("Module names prefixed with tilda (~) are currently loaded in WinMerge process.\r\n"));

// Platform stuff
	FileWriteString(_T("\r\n\r\nVersion information:\r\n"));
	FileWriteString(_T(" WinMerge.exe: "));
	FileWriteString(version.GetFixedProductVersion().c_str());

	String privBuild = version.GetPrivateBuild();
	if (!privBuild.empty())
	{
		FileWriteString(_T(" - Private build: "));
		FileWriteString(privBuild.c_str());
	}

	text = GetBuildFlags();
	FileWriteString(_T("\r\n Build config: "));
	FileWriteString(text.c_str());

	LPCTSTR szCmdLine = ::GetCommandLine();
	ASSERT(szCmdLine != NULL);

	// Skip the quoted executable file name.
	if (szCmdLine != NULL)
	{
		szCmdLine = _tcschr(szCmdLine, '"');
		if (szCmdLine != NULL)
		{
			szCmdLine += 1; // skip the opening quote.
			szCmdLine = _tcschr(szCmdLine, '"');
			if (szCmdLine != NULL)
			{
				szCmdLine += 1; // skip the closing quote.
			}
		}
	}

	// The command line include a space after the executable file name,
	// which mean that empty command line will have length of one.
	if (lstrlen(szCmdLine) < 2)
	{
		szCmdLine = _T(" none");
	}

	FileWriteString(_T("\r\n Command Line: "));
	FileWriteString(szCmdLine);

	FileWriteString(_T("\r\n Windows: "));
	text = GetWindowsVer();
	FileWriteString(text.c_str());

	FileWriteString(_T("\r\n"));
	WriteVersionOf1(1, _T("COMCTL32.dll"));
	WriteVersionOf1(1, _T("shlwapi.dll"));
	WriteVersionOf1(1, _T("MergeLang.dll"));
	WriteVersionOf1(1, _T("ShellExtension.dll"));
	WriteVersionOf1(1, _T("ShellExtensionU.dll"));
	WriteVersionOf1(1, _T("ShellExtensionX64.dll"));

// WinMerge settings
	FileWriteString(_T("\r\nWinMerge configuration:\r\n"));
	FileWriteString(_T(" Compare settings:\r\n"));

	WriteItemYesNo(2, _T("Ignore blank lines"), &m_diffOptions.bIgnoreBlankLines);
	WriteItemYesNo(2, _T("Ignore case"), &m_diffOptions.bIgnoreCase);
	WriteItemYesNo(2, _T("Ignore carriage return differences"), &m_diffOptions.bIgnoreEol);

	WriteItemWhitespace(2, _T("Whitespace compare"), &m_diffOptions.nIgnoreWhitespace);

	WriteItemYesNo(2, _T("Detect moved blocks"), &m_miscSettings.bMovedBlocks);
	WriteItem(2, _T("Compare method"), m_compareSettings.nCompareMethod);
	WriteItemYesNo(2, _T("Stop after first diff"), &m_compareSettings.bStopAfterFirst);

	FileWriteString(_T("\r\n Other settings:\r\n"));
	WriteItemYesNo(2, _T("Automatic rescan"), &m_miscSettings.bAutomaticRescan);
	WriteItemYesNoInverted(2, _T("Simple EOL"), &m_miscSettings.bAllowMixedEol);
	WriteItemYesNo(2, _T("Automatic scroll to 1st difference"), &m_miscSettings.bScrollToFirst);
	WriteItemYesNo(2, _T("Backup original file"), &m_miscSettings.bBackup);

	FileWriteString(_T("\r\n Folder compare:\r\n"));
	WriteItemYesNo(2, _T("Identical files"), &m_viewSettings.bShowIdent);
	WriteItemYesNo(2, _T("Different files"), &m_viewSettings.bShowDiff);
	WriteItemYesNo(2, _T("Left Unique files"), &m_viewSettings.bShowUniqueLeft);
	WriteItemYesNo(2, _T("Right Unique files"), &m_viewSettings.bShowUniqueRight);
	WriteItemYesNo(2, _T("Binary files"), &m_viewSettings.bShowBinaries);
	WriteItemYesNo(2, _T("Skipped files"), &m_viewSettings.bShowSkipped);
	WriteItemYesNo(2, _T("Tree-mode enabled"), &m_viewSettings.bTreeView);

	FileWriteString(_T("\r\n File compare:\r\n"));
	WriteItemYesNo(2, _T("Preserve filetimes"), &m_miscSettings.bPreserveFiletimes);
	WriteItemYesNo(2, _T("Match similar lines"), &m_miscSettings.bMatchSimilarLines);

	FileWriteString(_T("\r\n Editor settings:\r\n"));
	WriteItemYesNo(2, _T("View Whitespace"), &m_miscSettings.bViewWhitespace);
	WriteItemYesNo(2, _T("Merge Mode enabled"), &m_miscSettings.bMergeMode);
	WriteItemYesNo(2, _T("Show linenumbers"), &m_miscSettings.bShowLinenumbers);
	WriteItemYesNo(2, _T("Wrap lines"), &m_miscSettings.bWrapLines);
	WriteItemYesNo(2, _T("Syntax Highlight"), &m_miscSettings.bSyntaxHighlight);
	WriteItem(2, _T("Tab size"), m_miscSettings.nTabSize);
	WriteItemYesNoInverted(2, _T("Insert tabs"), &m_miscSettings.nInsertTabs);
	
// Font settings
	FileWriteString(_T("\r\n Font:\r\n"));
	FileWriteString(Fmt(_T("  Font facename: %s\r\n"), m_fontSettings.sFacename.c_str()));
	FileWriteString(Fmt(_T("  Font charset: %d (%s)\r\n"), m_fontSettings.nCharset, 
		FontCharsetName(m_fontSettings.nCharset).c_str()));

// System settings
	FileWriteString(_T("\r\nSystem settings:\r\n"));
	FileWriteString(_T(" codepage settings:\r\n"));
	WriteItem(2, _T("ANSI codepage"), GetACP());
	WriteItem(2, _T("OEM codepage"), GetOEMCP());
	WriteLocaleSettings(GetThreadLocale(), _T("Locale (Thread)"));
	WriteLocaleSettings(LOCALE_USER_DEFAULT, _T("Locale (User)"));
	WriteLocaleSettings(LOCALE_SYSTEM_DEFAULT, _T("Locale (System)"));

// Codepage settings
	WriteItemYesNo(1, _T("Detect codepage automatically for RC and HTML files"), &m_cpSettings.bDetectCodepage);
	WriteItem(1, _T("unicoder codepage"), getDefaultCodepage());

// Plugins
	FileWriteString(_T("\r\nPlugins:\r\n"));
	WriteItemYesNo(1, _T("Plugins enabled"), &m_miscSettings.bPluginsEnabled);
	FileWriteString(_T(" Unpackers: "));
	WritePluginsInLogFile(L"FILE_PACK_UNPACK");
	WritePluginsInLogFile(L"BUFFER_PACK_UNPACK");
	FileWriteString(_T("\r\n Prediffers: "));
	WritePluginsInLogFile(L"FILE_PREDIFF");
	WritePluginsInLogFile(L"BUFFER_PREDIFF");
	FileWriteString(_T("\r\n Editor scripts: "));
	WritePluginsInLogFile(L"EDITOR_SCRIPT");
	if (IsWindowsScriptThere() == FALSE)
		FileWriteString(_T("\r\n .sct scripts disabled (Windows Script Host not found)\r\n"));

	FileWriteString(_T("\r\n\r\n"));
	WriteArchiveSupport();

	CloseFile();

	return true;
}