Cmd_Ostat.cpp. #1

  • //
  • guest/
  • YourUncleBob/
  • p4win/
  • main/
  • gui/
  • p4api/
  • Cmd_Ostat.cpp.
  • View
  • Commits
  • Open Download .zip Download (11 KB)
//
// Copyright 1997 Nicholas J. Irias.  All rights reserved.
//
//

// Cmd_Ostat.cpp

#include "stdafx.h"
#include "p4win.h"
#include "MainFrm.h"
#include "Cmd_Ostat.h"
#include "Cmd_Fstat.h"
#include "cmd_Info.h"
#include "Cmd_Opened.h"
#include "Cmd_Resolved.h"
#include "Cmd_Unresolved.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

int compareOpenFiles( const void *arg1, const void *arg2 );
int compareUnresolvedFiles( const void *arg1, const void *arg2 );
	
IMPLEMENT_DYNCREATE(CCmd_Ostat, CP4Command)


CCmd_Ostat::CCmd_Ostat(CGuiClient *client) : CP4Command(client)
{
	m_ReplyMsg= WM_P4OSTAT;
	m_TaskName= "Ostat";
}


BOOL CCmd_Ostat::Run(BOOL allOpenFiles, int changeNumber/*-1*/, CStringList *files/*=NULL*/)
{
	m_AllOpenFiles=allOpenFiles;
	m_ChangeNumber=changeNumber;
	m_pSpecList=files;
	return CP4Command::Run();
}

void CCmd_Ostat::PreProcess(BOOL& done)
{
	Error e;
	POSITION pos;
	CObList *list = 0;
	CObList *mylist;

    // Set initial array sizes with a reasonable rate of
    // growth, to avoid continual re-alloc operations
    m_OpenArray.SetSize(0,500);
    m_UnresolvedArray.SetSize(0,500);
    m_ResolvedArray.SetSize(0,500);

	BOOL b = FALSE;
	if(GET_SERVERLEVEL() >= 19)			// 2005.1 or later?
	{
		// first make sure the client is valid
	    CCmd_Info cmd(m_pClient);
		cmd.Init( NULL, RUN_SYNC );
		if( cmd.Run( ) && !cmd.GetError() )
		{
			CP4Info const &info = cmd.GetInfo();
			if (info.m_ClientRoot.IsEmpty( ))
			{
				HWND hWnd= AfxGetMainWnd()->m_hWnd;
				if( hWnd != NULL )
				{
					::PostMessage(hWnd, WM_CLIENTERROR, 0, 0);
					m_FatalError= -1;
					done=TRUE;
					return;
				}
			}
		}

     	// Set up and run fstat synchronously
		CStringList strlist;
		CString str;
		str.Format(_T("//%s/..."), GET_P4REGPTR()->GetP4Client());
		strlist.AddHead(str);
	    CCmd_Fstat cmd0(m_pClient);
		cmd0.Init(NULL, RUN_SYNC);
		cmd0.SetIncludeAddedFiles( TRUE );
		if(cmd0.Run( FALSE, &strlist, TRUE, 0, TRUE, m_ChangeNumber ) && !cmd0.GetError())
			b = TRUE;
		cmd0.CloseConn(&e);
		// Copy the results from fstat -W
		if (b)
		{
	        mylist= cmd0.GetFileList();
			for( pos= mylist->GetHeadPosition(); pos!= NULL; )
				m_OpenArray.Add( mylist->GetNext(pos) );
		}
	}

	if (!b || m_AllOpenFiles)
	{
		// Set up and run Opened synchronously
		BOOL bFilter;
		CStringList filterList;
		CStringList *pList;
		CCmd_Opened cmd1(m_pClient);
		cmd1.Init(NULL, RUN_SYNC);
		if ((bFilter = GET_P4REGPTR()->FilterPendChgsByMyClient()) == 2)
		{
			CString filter = GET_P4REGPTR()->FilterPendChgsByPath();
			int i;
			while ((i = filter.Find(_T("//"), 2)) != -1)
			{
				CString str = filter.Left(i);
				str.TrimRight();
				filterList.AddTail(str);
				filter = filter.Mid(i);
			}
			filterList.AddTail(filter);
			pList = &filterList;
		}
		else
			pList = m_pSpecList;
		if(cmd1.Run(m_AllOpenFiles, bFilter, m_ChangeNumber, pList))
		{
			m_FatalError= cmd1.GetError();
			done=TRUE;
		}
		else
		{
			m_ErrorTxt= "Unable to Run Opened";
			m_FatalError=TRUE;
		}
		cmd1.CloseConn(&e);
		list= cmd1.GetList();
		// Copy the results from opened
		if(!m_FatalError && (list && list->GetCount() > 0))
		{
			for( pos= list->GetHeadPosition(); pos!= NULL; )
			{
				CP4FileStats *stats= (CP4FileStats *) list->GetNext(pos);
				if( b && ( stats->IsMyOpen() || stats->IsOtherUserMyClient() ) )
				{
					delete stats;
					continue;
				}
				m_OpenArray.Add( stats );
			}
		}
	}

	if(!m_FatalError && !m_OpenArray.IsEmpty())
	{
		if (list && list->GetCount() > 0)
		{
			for( pos= list->GetHeadPosition(); pos!= NULL; )
			{
				CP4FileStats *stats= (CP4FileStats *) list->GetNext(pos);
				if( b && ( stats->IsMyOpen() || stats->IsOtherUserMyClient() ) )
				{
					delete stats;
					continue;
				}
				m_OpenArray.Add( stats );
			}
		}

     	// Set up and run unresolved (p4 resolve-n)
	    CCmd_Unresolved cmd2(m_pClient);
		cmd2.Init(NULL, RUN_SYNC);
		if(cmd2.Run())
            m_FatalError= cmd2.GetError();
        else
		{
			m_ErrorTxt= "Unable to Run Unresolved";
			m_FatalError=TRUE;
		}

        if( !m_FatalError )
		{
			// Store a pointer to the list of unresolved files
			CObArray const *pArray= cmd2.GetArray();
			for( int i=0; i < pArray->GetSize(); i++)
			{
				CP4FileStats *stats= (CP4FileStats *) pArray->GetAt(i);
				m_UnresolvedArray.Add( stats->GetFullDepotPath());
				delete stats;
			}

			// Set up and run resolved (p4 resolved)
        	CCmd_Resolved cmd3(m_pClient);
			cmd3.Init(NULL, RUN_SYNC);
			if(cmd3.Run())
				m_FatalError= cmd3.GetError();
			else
			{
				m_ErrorTxt= "Unable to Run Resolved";
				m_FatalError=TRUE;
			}
            cmd3.CloseConn(&e);

			if( !m_FatalError )
			{
				// Store a pointer to the list of Resolved files
				CObArray const *pArray= cmd3.GetArray();
				for( int i=0; i < pArray->GetSize(); i++)
				{
					CP4FileStats *stats= (CP4FileStats *) pArray->GetAt(i);
					m_ResolvedArray.Add( stats->GetFullDepotPath());
					delete stats;
				}
			}
        }
	}

	if( !m_FatalError && m_OpenArray.GetSize() > 0 )
         // Sort the results from opened
        SortOpened();

    if( !m_FatalError && m_UnresolvedArray.GetSize() > 0 )
        // Sort the results from Unresolved
        SortUnresolved();

    if( !m_FatalError && m_ResolvedArray.GetSize() > 0 )
        // Sort the results from Unresolved
        SortResolved();

    
	///////////////
	// Update files in m_OpenList.  The array of opened files is sorted
    // by myopen+changeno+filename, so search should never look at another
    // user's open files.  Files appearing in the m_Unresolved list
	// must have the unresolved att set; Files appearing in the m_Resolved list
	// must have the resolved att set

	if(!m_FatalError && ((m_UnresolvedArray.GetSize() > 0) || (m_ResolvedArray.GetSize() > 0)))
	{
        int maxR= m_ResolvedArray.GetSize();
        int maxU= m_UnresolvedArray.GetSize();
        int maxO= m_OpenArray.GetSize();

        CString fName;
        CP4FileStats *stats;

		int i;
        for( i=0; i<maxU; i++)
        {
            fName= m_UnresolvedArray.GetAt(i);

            for( int j=0; j<maxO; j++ )
            {
                stats= (CP4FileStats *) m_OpenArray.GetAt(j);
                if(stats->IsMyOpen() && fName == stats->GetFullDepotPath())
                {
					// Update the unresolved flag for file 
					stats->SetUnresolved(TRUE);
					break;
				}
                if( !stats->IsMyOpen() )
                {
                    // It is possible that 'p4 resolve -n' returned unresolved files on
                    // my client that were opened by another user.  In 99.1 we may try to
                    // display these.  For now, do not show these files as unresolved, so
                    // break off the search for opened files as soon as we hit a file that
                    // is not my open.
                    break;
                }
            }
        }
        for( i=0; i<maxR; i++)
        {
            fName= m_ResolvedArray.GetAt(i);

            for( int j=0; j<maxO; j++ )
            {
                stats= (CP4FileStats *) m_OpenArray.GetAt(j);
                if(stats->IsMyOpen() && fName == stats->GetFullDepotPath())
                {
					// Update the resolved flag for file 
					stats->SetResolved(TRUE);
					break;
				}
                if( !stats->IsMyOpen() )
                {
                    // It is possible that 'p4 resolved' returned unresolved files on
                    // my client that were opened by another user.  In 99.1 we may try to
                    // display these.  For now, do not show these files as unresolved, so
                    // break off the search for opened files as soon as we hit a file that
                    // is not my open.
                    break;
                }
            }
        }
    }

    // Provide statistics if requested
    if( GET_P4REGPTR()->ShowCommandTrace( ) )
    {
        CString statistics;
        statistics.Format(_T("     Found %ld opened files with %ld unresolved files and %ld resolved files"), m_OpenArray.GetSize(), m_UnresolvedArray.GetSize(), m_ResolvedArray.GetSize());
        TheApp()->StatusAdd(statistics);
    }
    done=TRUE;
}

// to avoid having to call IS_NOCASE and branch for each compare, set up a 
// compare function pointer:
int (*pCompare)(LPCTSTR str1, LPCTSTR str2) = 0;

void setupCompare()
{
	// If server level not set, we also dont know if server is nocase
	ASSERT(GET_SERVERLEVEL());

	if(IS_NOCASE())
        pCompare = _tcsicmp;
    else
        pCompare = _tcscmp;
}

void CCmd_Ostat::SortOpened()
{
    // Sort the m_OpenArray of CP4FileStats according to:
    // 1) my open files first, other's open files later
    // 2) change number
    // 3) file name

    unsigned int size= m_OpenArray.GetSize();
    CObject **array= m_OpenArray.GetData();

    setupCompare();
    qsort( (void *) array, size, sizeof( CObject *), compareOpenFiles );
}

void CCmd_Ostat::SortUnresolved()
{
    // Sort the m_UnresolvedArray of CP4FileStats according to:
    // 1) my open files first, other's open files later
    // 2) change number
    // 3) file name

    unsigned int size= m_UnresolvedArray.GetSize();
    CString *array= m_UnresolvedArray.GetData();

    setupCompare();
    qsort( (void *) array, size, sizeof( CString * ), compareUnresolvedFiles );
}


void CCmd_Ostat::SortResolved()
{
    // Sort the m_ResolvedArray of CP4FileStats according to:
    // 1) my open files first, other's open files later
    // 2) change number
    // 3) file name

    unsigned int size= m_ResolvedArray.GetSize();
    CString *array= m_ResolvedArray.GetData();

    setupCompare();
    qsort( (void *) array, size, sizeof( CString * ), compareUnresolvedFiles );
}

// return <0 if arg1 < arg2, 0 if arg1=arg2, >0 if arg1 > arg2
int compareOpenFiles( const void *arg1, const void *arg2 )
{
    CP4FileStats *fs1= *((CP4FileStats **) arg1);
    CP4FileStats *fs2= *((CP4FileStats **) arg2);
    
    int result;

    // First compare whose file open it is.  My files sort to the top
    if( (result= fs2->IsMyOpen() - fs1->IsMyOpen()) != 0)
        goto done;

    // Next compare change number
    if( (result= fs1->GetOpenChangeNum() - fs2->GetOpenChangeNum()) != 0)
        goto done;
    
    ASSERT(pCompare);

    // Next compare user@client, for default changes only
    if( fs1->GetOpenChangeNum() == 0 )
        if( (result= pCompare(fs1->GetOtherUsers(), fs2->GetOtherUsers())) != 0)
            goto done;
 
    // Finally compare file name
    result= pCompare(fs1->GetFullDepotPath(), fs2->GetFullDepotPath());

done:
    return result;
}

// return <0 if arg1 < arg2, 0 if arg1=arg2, >0 if arg1 > arg2
int compareUnresolvedFiles( const void *arg1, const void *arg2 )
{
    CString *f1= (CString *) arg1;
    CString *f2= (CString *) arg2;
    ASSERT(pCompare);
    return pCompare(*f1,*f2);
}
# Change User Description Committed
#1 19924 YourUncleBob Populate -o //guest/perforce_software/p4win/...
//guest/YourUncleBob/p4win/.....
//guest/perforce_software/p4win/main/gui/p4api/Cmd_Ostat.cpp
#1 16169 perforce_software Move files to follow new path scheme for branches.
//guest/perforce_software/p4win/gui/p4api/Cmd_Ostat.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.