ultimatepp/uppsrc/ide/Browser/Base.cpp
cxl ae24688764 A++: fixed problems with typecast operator, navigator scope double-click goes to the first item
git-svn-id: svn://ultimatepp.org/upp/trunk@609 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2008-11-05 21:36:41 +00:00

303 lines
6 KiB
C++

#include "Browser.h"
#define LTIMING(x) // RTIMING(x)
#define LLOG(x)
static const char s_dbver[] = "CPP-BASE 2.36";
void GC_Cache()
{
String cfg = ConfigFile("cfg");
FindFile ff(AppendFileName(cfg, "*.cache"));
Time tm0 = ToTime(GetSysDate() - 20);
while(ff) {
if(ff.IsFile() && Time(ff.GetLastWriteTime()) > tm0)
FileDelete(AppendFileName(cfg, ff.GetName()));
ff.Next();
}
}
String CacheFile(const String& res)
{
return AppendFileName(ConfigFile("cfg"), MD5String(res) + ".cache");
}
CppBase& CodeBase()
{
static CppBase b;
return b;
}
ArrayMap<String, BrowserFileInfo>& FileSet()
{
static ArrayMap<String, BrowserFileInfo> x;
return x;
}
Vector<Browser *>& RBrowser()
{
static Vector<Browser *> bp;
return bp;
}
static bool s_console;
static String s_file;
void BrowserScanError(int line, const String& text)
{
if(s_console)
PutConsole(String().Cat() << s_file << " (" << line << "): " << text);
}
void SaveCodeBase()
{
LTIMING("SaveCodeBase");
RealizeDirectory(ConfigFile("cfg"));
GC_Cache();
CppBase& base = CodeBase();
if(base.GetCount() == 0)
return;
ArrayMap<String, BrowserFileInfo>& fileset = FileSet();
ArrayMap<String, StringStream> out;
String s;
for(int j = 0; j < base.GetCount(); j++) {
Array<CppItem>& n = base[j];
for(int k = 0; k < n.GetCount(); k++) {
CppItem& m = n[k];
StringStream& o = out.GetAdd(GetCppFile(m.file));
s = base.GetKey(j);
o % s;
o % m;
}
}
const Workspace& wspc = GetIdeWorkspace();
for(int i = 0; i < wspc.GetCount(); i++) {
String package = wspc[i];
FileOut fo(CacheFile(package));
s = s_dbver;
fo % s;
for(int i = 0; i < fileset.GetCount(); i++)
if(fileset[i].package == package) {
String fn = fileset.GetKey(i);
String q = out.GetAdd(fn).GetResult();
BrowserFileInfo& f = fileset[i];
fo % fn;
fo % f.file;
fo % f.time;
fo % q;
}
}
}
void LoadCodeBase(Progress& pi)
{
LTIMING("LoadCodeBase");
CppBase& base = CodeBase();
ArrayMap<String, BrowserFileInfo>& fileset = FileSet();
String s;
const Workspace& wspc = GetIdeWorkspace();
pi.SetText("Assist++ loading packages");
pi.SetTotal(wspc.GetCount());
pi.SetPos(0);
for(int i = 0; i < wspc.GetCount(); i++) {
pi.Step();
String package = wspc[i];
FileIn in(CacheFile(package));
in.LoadThrowing();
if(in) {
try {
in % s;
if(s != s_dbver)
throw LoadingError();
while(!in.IsEof()) {
String fn;
in % fn;
BrowserFileInfo& f = fileset.GetAdd(fn);
in % f.file;
in % f.time;
f.package = package;
String q;
in % q;
StringStream ss(q);
ss.LoadThrowing();
while(!ss.IsEof()) {
String s;
ss % s;
CppItem& m = base.GetAdd(s).Add();
ss % m;
m.file = GetCppFileIndex(fn);
}
}
}
catch(LoadingError) {
CodeBase().Clear();
fileset.Clear();
return;
}
}
}
}
void FinishBase()
{
TimeStop tm;
Qualify(CodeBase());
}
void ReQualifyCodeBase()
{
Qualify(CodeBase());
}
Vector<String> SortedNests()
{
LTIMING("SortedNests()");
CppBase& base = CodeBase();
Vector<String> n;
for(int i = 0; i < base.GetCount(); i++)
if(!base.IsUnlinked(i))
n.Add(base.GetKey(i));
Sort(n);
return n;
}
void UpdateCodeBase(Progress& pi)
{
Index<String> fp;
Vector<String> scan;
ArrayMap<String, BrowserFileInfo>& set = FileSet();
const Workspace& wspc = GetIdeWorkspace();
CppBase& base = CodeBase();
pi.SetText("Assist++ checking packages");
pi.SetTotal(wspc.GetCount());
pi.SetPos(0);
for(int i = 0; i < wspc.GetCount(); i++) {
pi.Step();
const Package& pk = wspc.GetPackage(i);
String n = wspc[i];
for(int i = 0; i < pk.file.GetCount(); i++) {
String path = SourcePath(n, pk.file[i]);
String ext = ToUpper(GetFileExt(path));
if(ext == ".C" || ext == ".CPP" || ext == ".CC" || ext == ".CXX" ||
ext == ".H" || ext == ".HPP" || ext == ".HH" || ext == ".HXX" ||
ext == ".LAY") {
fp.Add(path);
int q = set.Find(path);
Time tm = FileGetTime(path);
if(q < 0 || set[q].time != tm)
scan.Add(path);
BrowserFileInfo& bf = set.GetAdd(path);
bf.package = n;
bf.file = pk.file[i];
bf.time = tm;
}
}
}
Vector<String> remove(scan, 1);
Vector<int> rm;
for(int i = 0; i < set.GetCount(); i++)
if(fp.Find(set.GetKey(i)) < 0) {
remove.Add(set.GetKey(i));
rm.Add(i);
}
if(remove.GetCount() == 0)
return;
set.Remove(rm);
Remove(base, remove);
if(scan.GetCount()) {
pi.SetTotal(scan.GetCount());
pi.SetPos(0);
pi.AlignText(ALIGN_LEFT);
Vector<String> ignore = IgnoreList();
for(int i = 0; i < scan.GetCount(); i++) {
s_file = scan[i];
pi.SetText(s_file);
pi.Step();
String ext = ToUpper(GetFileExt(s_file));
if(ext == ".LAY")
ScanLayFile(s_file);
else {
FileIn fi(s_file);
Parse(fi, ignore, base, s_file, callback(BrowserScanError));
}
}
}
}
void CodeBaseScan(Stream& s, const String& fn)
{
LTIMING("CodeBaseScan");
TimeStop tm;
CppBase& base = CodeBase();
LLOG("Scan2 " << tm);
Vector<String> remove;
remove.Add(fn);
Remove(base, remove);
LLOG("Scan3 " << tm);
Parse(s, IgnoreList(), base, fn, CNULL);
LLOG("Scan4 " << tm);
FinishBase();
LLOG("Scan total " << tm);
LLOG("---------");
}
void CodeBaseScanLay(const String& fn)
{
LTIMING("CodeBaseScanLay");
Vector<String> before = SortedNests();
CppBase& base = CodeBase();
Vector<String> remove;
remove.Add(fn);
Remove(base, remove);
ScanLayFile(fn);
FinishBase();
}
void ClearCodeBase()
{
CodeBase().Clear();
FileSet().Clear();
}
void StartCodeBase()
{
static int start;
if(start) return;
start++;
if(CodeBase().GetCount() == 0) {
Progress pi;
pi.Title("Assist++");
LoadCodeBase(pi);
UpdateCodeBase(pi);
FinishBase();
}
start--;
}
void SyncCodeBase()
{
if(CodeBase().GetCount()) {
Progress pi;
pi.Title("Assist++");
UpdateCodeBase(pi);
FinishBase();
}
}
void RescanCodeBase()
{
ClearCodeBase();
s_console = true;
Progress pi;
pi.Title("Assist++");
UpdateCodeBase(pi);
FinishBase();
s_console = false;
}
bool ExistsBrowserItem(const String& item)
{
return GetCodeRefItem(item);
}