// // Copyright 1997 Nicholas J. Irias. All rights reserved. // // // Cmd_Diff2.cpp #include "stdafx.h" #include "p4win.h" #include "cmd_diff2.h" #include "cmd_prepbrowse.h" #include "cmd_where.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif IMPLEMENT_DYNCREATE(CCmd_Diff2, CP4Command) CCmd_Diff2::CCmd_Diff2(CGuiClient *client) : CP4Command(client) { m_ReplyMsg= WM_P4DIFF2; m_TaskName= _T("Diff2"); } BOOL CCmd_Diff2::Run(LPCTSTR file1, LPCTSTR file2, int rev1, int rev2, CString &fileType1, CString &fileType2, BOOL bLocal1, BOOL bLocal2, BOOL bDoIt/*=FALSE*/) { // Record the args m_FileName[0]=file1; m_FileName[1]=file2; m_FileRev[0]=rev1; m_FileRev[1]=rev2; m_FileType[0]=fileType1; m_FileType[1]=fileType2; m_LocalFlag[0]=bLocal1; m_LocalFlag[1]=bLocal2; m_DoIt=bDoIt; if (bDoIt) { ClearArgs(); AddArg(_T("diff2")); AddArg(_T("-q")); AddArg(m_FileName[0]); AddArg(m_FileName[1]); } return CP4Command::Run(); } void CCmd_Diff2::PreProcess(BOOL& done) { m_InfoText.Empty(); // If we are going to actually run the command on the server // then there is no preprocessing to do. if (m_DoIt) { done=FALSE; return; } int i; Error e; CString fn1; CString fn2; BOOL isTextual1; BOOL isTextual2; BOOL isUnicode1; BOOL isUnicode2; BOOL isUtf161; BOOL isUtf162; BOOL success; // Get the first file if (m_FileRev[0] >= 0 && (i = m_FileName[0].FindOneOf(_T("@#"))) != -1) m_FileName[0] = m_FileName[0].Left(i); if (!m_LocalFlag[0]) { CCmd_PrepBrowse cmd1(m_pClient); cmd1.Init(NULL, RUN_SYNC, HOLD_LOCK); success= cmd1.Run(m_FileName[0], m_FileType[0], m_FileRev[0]); cmd1.CloseConn(&e); m_FatalError= cmd1.GetError(); m_ErrorTxt= cmd1.GetErrorText(); if( !success || m_FatalError || cmd1.NoFileAtThatRev() ) { done=TRUE; return; } fn1 = cmd1.GetTempName(); isTextual1 = cmd1.GetTempFile()->IsTextual(); isUnicode1 = cmd1.GetTempFile()->IsUnicode(); isUtf161 = (cmd1.GetTempFile()->GetType() & FST_MASK) == FST_UTF16; } else { if (m_FileName[0].GetAt(1) != _T(':')) { success = FALSE; CCmd_Where cmd(m_pClient); cmd.Init(NULL, RUN_SYNC, HOLD_LOCK); if ( cmd.Run(m_FileName[0]) && !cmd.GetError() && cmd.GetDepotFiles()->GetCount() ) { m_FileName[0] = cmd.GetLocalSyntax(); success = TRUE; } cmd.CloseConn(&e); if( !success ) { m_FatalError = TRUE; m_ErrorTxt.FormatMessage(IDS_UNABLE_TO_CONVERT_s_TO_LOCAL_SYNTAX, m_FileName[0]); done=TRUE; return; } } fn1 = m_FileName[0].GetBuffer(m_FileName[0].GetLength()+1); isUtf161 = (m_FileType[0].Find(_T("utf16")) != -1); isUnicode1 = isUtf161 || (m_FileType[0].Find(_T("unicode")) != -1); isTextual1 = isUnicode1 || (m_FileType[0].Find(_T("text")) != -1); } // Get the second file if (m_FileRev[1] >= 0 && (i = m_FileName[1].FindOneOf(_T("@#"))) != -1) m_FileName[1] = m_FileName[1].Left(i); if (!m_LocalFlag[1]) { CCmd_PrepBrowse cmd2(m_pClient); cmd2.Init(NULL, RUN_SYNC, HOLD_LOCK); success= cmd2.Run(m_FileName[1], m_FileType[1], m_FileRev[1]); cmd2.CloseConn(&e); m_FatalError= cmd2.GetError(); m_ErrorTxt= cmd2.GetErrorText(); if( !success || m_FatalError || cmd2.NoFileAtThatRev() ) { done=TRUE; return; } fn2 = cmd2.GetTempName(); isTextual2 = cmd2.GetTempFile()->IsTextual(); isUnicode2 = cmd2.GetTempFile()->IsUnicode(); isUtf162 = (cmd2.GetTempFile()->GetType() & FST_MASK) == FST_UTF16; } else { if (m_FileName[1].GetAt(1) != _T(':')) { success = FALSE; CCmd_Where cmd(m_pClient); cmd.Init(NULL, RUN_SYNC, HOLD_LOCK); if ( cmd.Run(m_FileName[1]) && !cmd.GetError() && cmd.GetDepotFiles()->GetCount() ) { m_FileName[1] = cmd.GetLocalSyntax(); success = TRUE; } cmd.CloseConn(&e); if( !success ) { m_FatalError = TRUE; m_ErrorTxt.FormatMessage(IDS_UNABLE_TO_CONVERT_s_TO_LOCAL_SYNTAX, m_FileName[1]); done=TRUE; return; } } fn2 = m_FileName[1].GetBuffer(m_FileName[1].GetLength()+1); isUtf162 = (m_FileType[1].Find(_T("utf16")) != -1); isUnicode2 = isUtf161 || (m_FileType[1].Find(_T("unicode")) != -1); isTextual2 = isUnicode2 || (m_FileType[1].Find(_T("text")) != -1); } // check to see if we have a binary filetype for either one of the files // and if so, has the user specified their own diff program and does it handle binary files // if using p4diff or their diff doesn't handle binary, just use internal Compare function // // If dealing with binary files, get the file extension, if any, // and find out if it has an associated diff for that extension CString appName; appName.Empty(); BOOL b = (!isTextual1 || !isTextual2) && !GET_P4REGPTR()->GetDiffAppIsBinary(); if ( b ) { CString extension = GetFilesExtension(fn2); if(!extension.IsEmpty()) appName= GET_P4REGPTR()->GetAssociatedDiff(extension); } if ( b && appName.IsEmpty() ) { FileSys *f1 = FileSys::Create( FST_BINARY ); FileSys *f2 = FileSys::Create( FST_BINARY ); f1->Set( CharFromCString(fn1) ); f2->Set( CharFromCString(fn2) ); if( f1->Compare( f2, &e ) ) { m_InfoText.Format(_T("Binary files differ but unable to display diff:\n\n%s,\n%s"), m_FileName[0], m_FileName[1]); TheApp()->StatusAdd(m_InfoText); if (m_Output2Dlg) m_InfoText.Empty(); } else { m_InfoText.Format(_T("Binary files identical:\n\n%s,\n%s"), m_FileName[0], m_FileName[1]); TheApp()->StatusAdd(m_InfoText); if (m_Output2Dlg) m_InfoText.Empty(); } delete f1; delete f2; } else // both are text or user's diff can handle binary files { CString errorText; CString buf1; CString buf2; BOOL isUnicode = isUnicode1 + isUnicode2; if (isUnicode) { if (isUnicode != 2) { if (IDYES != AfxMessageBox(IDS_UNICODETEXTMIX, MB_ICONQUESTION|MB_DEFBUTTON2|MB_YESNO)) { done=TRUE; return; } } if (isUtf161 || isUtf162) isUnicode = 16; } if (m_FileRev[0] > 0) buf1.Format(_T("%s#%ld"), m_FileName[0], m_FileRev[0]); else buf1.Format(_T("%s"), m_FileName[0]); if (m_FileRev[1] > 0) buf2.Format(_T("%s#%ld"), m_FileName[1], m_FileRev[1]); else buf2.Format(_T("%s"), m_FileName[1]); if( !TheApp()->RunApp(DIFF_APP, RA_NOWAIT, NULL, isUnicode, NULL, errorText, fn1, fn2, _T("-l"), buf1, _T("-r"), buf2) ) TheApp()->StatusAdd(errorText, SV_ERROR ); } // Note: // By setting done=TRUE, we prevent the main ExecCommand loop from running, // so this command will consist only of the subcommands that were invoked // in PreProcess() done=TRUE; } void CCmd_Diff2::OnOutputInfo(char level, LPCTSTR data, LPCTSTR msg) { if (m_DoIt && level == _T('0')) { if (m_Output2Dlg) m_InfoText += CString(msg) + _T('\n'); else TheApp()->StatusAdd(msg); } else CP4Command::OnOutputInfo(level, data, msg); } BOOL CCmd_Diff2::HandledCmdSpecificError(LPCTSTR errBuf, LPCTSTR errMsg ) { if ( StrStr(errBuf, _T("No file(s) to diff")) ) { TheApp()->StatusAdd(m_Output2Dlg ? LoadStringResource(IDS_NOFILESDIFFER) : errMsg, SV_COMPLETION); return TRUE ; } return ( FALSE ); }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 16169 | perforce_software | Move files to follow new path scheme for branches. | ||
//guest/perforce_software/p4win/gui/p4api/Cmd_Diff2.cpp | |||||
#1 | 8562 | Matt Attaway |
These feet never stop running. Initial commit of the P4Win source code. To the best of our knowledge this compiles and runs using the 2013.3 P4 API and VS 2010. Expect a few changes as we refine the build process. Please post any build issues to the forums. |