/** * @brief Generate report and save it to file. * @param [out] errStr Empty if succeeded, otherwise contains error message. * @return TRUE if report was created, FALSE if user canceled report. */ BOOL DirCmpReport::GenerateReport(String &errStr) { ASSERT(m_pList != NULL); ASSERT(m_pFile == NULL); BOOL bRet = FALSE; DirCmpReportDlg dlg; if (dlg.DoModal() == IDOK) try { WaitStatusCursor waitstatus(IDS_STATUS_CREATEREPORT); if (dlg.m_bCopyToClipboard) { if (!CWnd::GetSafeOwner()->OpenClipboard()) return FALSE; if (!EmptyClipboard()) return FALSE; CSharedFile file(GMEM_DDESHARE|GMEM_MOVEABLE|GMEM_ZEROINIT); m_pFile = &file; GenerateReport(dlg.m_nReportType); SetClipboardData(CF_TEXT, file.Detach()); // If report type is HTML, render CF_HTML format as well if (dlg.m_nReportType == REPORT_TYPE_SIMPLEHTML) { // Reconstruct the CSharedFile object file.~CSharedFile(); file.CSharedFile::CSharedFile(GMEM_DDESHARE|GMEM_MOVEABLE|GMEM_ZEROINIT); // Write preliminary CF_HTML header with all offsets zero static const char header[] = "Version:0.9\n" "StartHTML:%09d\n" "EndHTML:%09d\n" "StartFragment:%09d\n" "EndFragment:%09d\n"; static const char start[] = "<html><body>\n<!--StartFragment -->"; static const char end[] = "\n<!--EndFragment -->\n</body>\n</html>\n"; char buffer[256]; int cbHeader = wsprintfA(buffer, header, 0, 0, 0, 0); file.Write(buffer, cbHeader); file.Write(start, sizeof start - 1); GenerateHTMLHeaderBodyPortion(); GenerateXmlHtmlContent(false); file.Write(end, sizeof end); // include terminating zero DWORD size = GetLength32(file); // Rewrite CF_HTML header with valid offsets file.SeekToBegin(); wsprintfA(buffer, header, cbHeader, size - 1, cbHeader + sizeof start - 1, size - sizeof end + 1); file.Write(buffer, cbHeader); SetClipboardData(CF_HTML, GlobalReAlloc(file.Detach(), size, 0)); } CloseClipboard(); } if (!dlg.m_sReportFile.IsEmpty()) { String path; SplitFilename(dlg.m_sReportFile, &path, NULL, NULL); if (!paths_CreateIfNeeded(path.c_str())) { errStr = LoadResString(IDS_FOLDER_NOTEXIST); return FALSE; } CFile file(dlg.m_sReportFile, CFile::modeWrite|CFile::modeCreate|CFile::shareDenyWrite); m_pFile = &file; GenerateReport(dlg.m_nReportType); } bRet = TRUE; } catch (CException *e) { e->ReportError(MB_ICONSTOP); e->Delete(); } m_pFile = NULL; return bRet; }
/** * @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; }