// // 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 | 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. |