/***************************************************************************/
/* NOTE: */
/* This document is copyright (c) by Oz Solomonovich, and is bound by the */
/* MIT open source license (www.opensource.org/licenses/mit-license.html). */
/* See License.txt for more information. */
/***************************************************************************/
// PrjStats.cpp: implementation of the PrjStats class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "linecount.h"
#include "PrjStats.h"
#include "FileParser.h"
#include "ParserManager.h"
#include "ProgressDlg.h"
#include "Config.h"
#include "Utils.h"
#include "WorkspaceInfo.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
CMap<CString, LPCTSTR, CFileInfo, CFileInfo&> s_mapStats;
ProjectList::~ProjectList()
{
POSITION p = GetHeadPosition();
while (p)
{
delete GetNext(p);
}
}
int CalculateMixedLines(int iLinesTotal, int iLinesCode, int iLinesComments,
int iLinesBlank)
{
return iLinesCode + iLinesComments - (iLinesTotal - iLinesBlank);
}
void ProcessMessages(CWnd &cwnd)
{
MSG msg;
// process all messages pending in the queue
while (::PeekMessage(&msg, cwnd.m_hWnd, 0, 0, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
void ResetStats()
{
s_mapStats.RemoveAll();
}
bool UpdateStats(IWorkspaceInfo *pWI, ProjectList& projects)
{
int cFiles = 0;
CProgressDlg dlgProgress;
dlgProgress.Create(dlgProgress.IDD);
// count files
POSITION p = projects.GetHeadPosition();
while (p)
{
IWorkspaceProject *pPrj = projects.GetNext(p);
cFiles += pPrj->GetFileCount();
}
bool bInitialShowDlg = false;
bool bComplete = true;
int cCounted = 0;
CString sTemplateTop, sFiles, cStr;
sTemplateTop.LoadString(IDS_MSG_PROGRESS_COUNTING);
sFiles.Format("%02d", cFiles);
char full_path[_MAX_PATH];
CParserManager::PairArray arrPairs;
CParserManager::Get().GetPairs(arrPairs);
CStringList lstFileExclusions;
cStr = cfg_sFileIgnoreList;
cStr.MakeLower();
String2StringList(cStr, LIST_DELIMITER, lstFileExclusions);
// count files
if (cFiles)
{
dlgProgress.m_ProgressCtrl.SetRange(0, cFiles - 1);
dlgProgress.UpdateData(FALSE);
POSITION p = projects.GetHeadPosition();
while (p)
{
IWorkspaceProject *pPrj = projects.GetNext(p);
// Added Block jdk - see if this project file is in the global exclusion list
bool bDoProject = true;
cStr = pPrj->GetName();
cStr.MakeLower();
POSITION posFile = lstFileExclusions.GetHeadPosition();
CString s;
while (posFile)
{
CString& sFileFromList =
lstFileExclusions.GetNext(posFile);
s.Format("*%s", sFileFromList);
int start = 0;
if (sFileFromList.FindOneOf("\\/") < 0)
{
start = cStr.ReverseFind('\\') + 1;
}
if (wildcmp(s, cStr.Mid(start)))
{
bDoProject = false;
break;
}
}
// End Added Block
// Note - we don't break here if bDoProject is false because
// we want the file stats record to be created and set as
// 'filtered'.
const cFiles = pPrj->GetFileCount();
IProjectFile *pFile = NULL;
for (int f = 0; f < cFiles; ++f)
{
delete pFile;
pFile = pPrj->GetFile(f);
if (bInitialShowDlg && !dlgProgress.IsWindowVisible())
{
bComplete = false;
break;
}
++cCounted;
_fullpath(full_path, pFile->GetPath(),
countof(full_path));
CFileInfo& info = s_mapStats[full_path];
IFileParser *pParser = NULL;
if (info.m_stat != CFileInfo::full)
{
info.m_stat = CFileInfo::filtered; // assume at the moment
info.SetFileName(full_path);
bool bDoParse = false;
// see if the extension is in our list
cStr = info.m_sFileExt.IsEmpty()? "" : info.m_sFileExt.Mid(1);
cStr.MakeLower();
for (int iPair = 0; iPair < arrPairs.GetSize(); ++iPair)
{
if (wildcmp(arrPairs[iPair].sExt, cStr))
{
bDoParse = true;
pParser = arrPairs[iPair].pParser;
break;
}
}
// see if this file/path is in the global exclusion list
if (bDoParse)
{
cStr = info.m_sFullFileName;
cStr.MakeLower();
POSITION posFile = lstFileExclusions.GetHeadPosition();
CString s;
while (posFile)
{
CString& sFileFromList =
lstFileExclusions.GetNext(posFile);
s.Format("*%s", sFileFromList);
if (wildcmp(s, cStr))
{
bDoParse = false;
break;
}
}
}
if (bDoParse && bDoProject)
{
CString sCounted, sPerCent;
sCounted.Format("%02d", cCounted);
sPerCent.Format("%d", cCounted * 100 / cFiles);
dlgProgress.m_sTextTop = sTemplateTop;
dlgProgress.m_sTextTop.Replace("%1", sCounted);
dlgProgress.m_sTextTop.Replace("%2", sFiles);
dlgProgress.m_sTextTop.Replace("%3", sPerCent);
dlgProgress.m_sTextBottom = pFile->GetPath();
dlgProgress.UpdateData(FALSE);
dlgProgress.m_ProgressCtrl.SetPos(cCounted);
if (!bInitialShowDlg)
{
bInitialShowDlg = true;
dlgProgress.ShowWindow(SW_SHOW);
dlgProgress.RedrawWindow();
}
ProcessMessages(dlgProgress);
info.m_stat = CFileInfo::file_error; // assume the worst
ifstream ifs(info.m_sFullFileName,
ios::in | ios::nocreate);
if (ifs.good())
{
ASSERT(pParser != NULL);
pParser->ParseFile(ifs, info);
}
}
}
}
delete pFile;
}
}
dlgProgress.DestroyWindow();
return bComplete;
}
CFileInfo& GetStats(LPCTSTR pszFullFileName)
{
char full_path[1024];
_fullpath(full_path, pszFullFileName, countof(full_path));
return s_mapStats[full_path];
}