Cmd_Diff2.cpp. #1

  • //
  • guest/
  • YourUncleBob/
  • p4win/
  • main/
  • gui/
  • p4api/
  • Cmd_Diff2.cpp.
  • View
  • Commits
  • Open Download .zip Download (7 KB)
//
// 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 19924 YourUncleBob Populate -o //guest/perforce_software/p4win/...
//guest/YourUncleBob/p4win/.....
//guest/perforce_software/p4win/main/gui/p4api/Cmd_Diff2.cpp
#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.