|
// Copyright (C) 2011 Fog Creek Software
// Copyright (C) 2009 Adrian Buehlmann
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdafx.h"
#include "DirectoryStatus.h"
#include "THgStatus.h"
#include "TortoiseUtils.h"
char CDirectoryStatus::Status(CString strRelPath) const
{
bool bAdded = false;
bool bModified = false;
strRelPath += '/';
POSITION position = m_listEntries.GetHeadPosition();
while (position != NULL)
{
const CEntry& rEntry = m_listEntries.GetNext(position);
if (strRelPath.IsEmpty() || rEntry.strPath.Left(strRelPath.GetLength()) == strRelPath)
{
if (rEntry.chStatus == 'm' || rEntry.chStatus == 'r')
{
bModified = true;
break;
}
if (rEntry.chStatus == 'a')
{
bAdded = true;
}
}
}
if (bModified) return 'M';
if (bAdded) return 'A';
return 'C';
}
int CDirectoryStatus::Read(const CString& strHgRoot, const CString& strCwd)
{
m_listEntries.RemoveAll();
m_bNoIcons = false;
CString strStatusPath = strHgRoot + "\\.hg\\thgstatus";
CAtlFile file;
if (FAILED(file.Create(strStatusPath, GENERIC_READ,
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING)))
{
ATLTRACE("CDirectoryStatus::read: can't open '%s'\n", (LPCTSTR)strStatusPath);
CString p = (strCwd.GetLength() < strHgRoot.GetLength() ? strHgRoot : strCwd);
CTHgStatus::Update(strStatusPath);
return 0;
}
CDirectoryStatus::CEntry e;
int nRes = 1;
const CString strNoIcons = "@@noicons";
CString strLine;
for (;;)
{
strLine.Empty();
char chStatus;
for (;;)
{
if (FAILED(file.Read(&chStatus, sizeof(char)))) goto close;
if (chStatus == '\n') break;
strLine.AppendChar(chStatus);
if (strLine.GetLength() > 1000)
{
nRes = 0;
goto close;
}
}
if (StartsWith(strLine, strNoIcons))
{
m_bNoIcons = true;
goto close;
}
if (strLine.IsEmpty()) goto close;
e.chStatus = strLine[0];
CString strPath;
if (strLine.GetLength() > 1)
{
strPath = strLine.Mid(1).MakeLower();
}
strPath.AppendChar('/');
e.strPath = strPath;
m_listEntries.AddTail(e);
}
close:
file.Close();
ATLTRACE("DirectoryStatus::read(%d): done. %d entries read. noicons_ = %d\n",
m_listEntries.GetCount(), m_bNoIcons);
return nRes;
}
struct CCacheEntry
{
CString strHgRoot;
CDirectoryStatus ds;
bool bReadFailed;
unsigned uTickCount;
CCacheEntry() : bReadFailed(false), uTickCount(0) {}
};
CDirectoryStatus* CDirectoryStatus::Get(const CString& strHgRoot,
const CString& strCwd)
{
static CCacheEntry ce;
unsigned tc = ::GetTickCount();
if (ce.strHgRoot != strHgRoot || (tc - ce.uTickCount) > 2000)
{
ce.strHgRoot.Empty();
ce.bReadFailed = (ce.ds.Read(strHgRoot, strCwd) == 0);
ce.strHgRoot = strHgRoot;
ce.uTickCount = ::GetTickCount();
}
return (ce.bReadFailed ? 0 : &ce.ds);
}
|
Loading...