// HNode.cpp: implementation of the HNode class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "Peeper.h" #include "HNode.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// //CArray HNode::Guff; //DWORD HNode::ObjCount; HNode *HNode::Create() { return new HNode; } void HNode::Delete(HNode *node) { delete node; } HNode::HNode() { Children.SetSize(0,5); Clones.SetSize(0,5); Original=NULL; Parent=NULL; Item=NULL; Flag=0; } bool HNode::AddLocalFile(const CString &fname,const CString &path) { return NewChild()->ParseLocalFile(fname,path); } bool HNode::ParseLocalFile(const CString &fname,const CString &path) { FName=fname; Path=path; Flag=0; FName.Replace('/','\\'); int loc=FName.ReverseFind('\\'); if(loc>=0) // If path was included add it { Path+=FName.Left(loc+1); FName=FName.Mid(loc+1); } CString fbuf; if(SysGetFile(FName,Path,fbuf)) { return Parse(fbuf.GetBuffer(0)); fbuf.ReleaseBuffer(); } else { return ParseGlobalFile(fname); } } bool HNode::ParseGlobalFile(const CString &fname) { FName=fname; Flag=0; CString path,fbuf; if(PathMan->GetFile(FName,Path,fbuf)) { FName.Replace('/','\\'); int loc=FName.ReverseFind('\\'); if(loc>=0) // If path was included add it { Path+=FName.Left(loc+1); FName=FName.Mid(loc+1); } return Parse(fbuf.GetBuffer(0)); } else { Flag|=HN_NOTFOUND; } return true; } bool HNode::IsAbove(HNode *node) { if(IsSameName(node)) return true; if(Parent==NULL) return false; return Parent->IsAbove(node); } bool HNode::Parse(char *fbuf) { if(Parent && Parent->IsAbove(this)) // If the file is in the Tree we have a loop { Flag|=HN_LOOP; return false; } // If the file has been parsed before copy it if(CopyFromTree(this)) return true; int start=0; int bufsize=strlen(fbuf); bool foundinclude=false; int sd,ed; for(;;) { for(foundinclude=false;!foundinclude;) { while( !(fbuf[start]=='/' && (fbuf[start+1]=='/') || fbuf[start+1]=='*') && fbuf[start]!='#' && start=bufsize) return true; } else if((fbuf[start]=='/') && (fbuf[start+1]=='*')) { start+=2; if(start>=bufsize) {Flag|=HN_PARSEERROR; return true;} while(!(fbuf[start]!='*' && fbuf[start+1]!='/') && start=bufsize) {Flag|=HN_PARSEERROR; return true;} } else { if(start>=bufsize) return true; start++; while((fbuf[start]==' ' || fbuf[start]=='\t') && fbuf[start]!='\x0D') start++; // swallow white spaces if(!strncmp(fbuf+start,"include",7)) { start+=7; foundinclude=true; } } } for(sd=start;fbuf[sd]!='\"' && fbuf[sd]!='\x0D';sd++); if(fbuf[sd]=='\"') { sd++; for(ed=sd;fbuf[ed]!='\"' && fbuf[ed]!='\x0D';ed++); if(fbuf[ed]!='\"') { Flag|=HN_PARSEERROR; return true; } fbuf[ed]=0; NewChild()->ParseLocalFile(fbuf+sd,Path); } else { for(sd=start;fbuf[sd]!='<' && fbuf[sd]!='\x0D';sd++); if(fbuf[sd]=='\x0D') { Flag|=HN_PARSEERROR; return true; } sd++; for(ed=sd;fbuf[ed]!='>' && fbuf[ed]!='\x0D';ed++); if(fbuf[ed]!='>') { Flag|=HN_PARSEERROR; return true; } fbuf[ed]=0; NewChild()->ParseGlobalFile(fbuf+sd); } start=ed+2; } } bool HNode::CopyFromTreeDown(HNode *dest) { if(IsCopy()) return false; if(IsSameName(dest)) { dest->Copy(this); return true; } else { int size=Children.GetSize(); for(int i=0;iCopyFromTreeDown(dest)) return true; } } return false; } bool HNode::CopyFromTree(HNode *dest) { if(!Parent) return false; for(int i=0;iChildren.GetSize();i++) if(Parent->Children[i]!=this && !(Parent->Children[i]->Flag&HN_LOOP)) { if(Parent->Children[i]->CopyFromTreeDown(dest)) return true; } return Parent->CopyFromTree(dest); } void HNode::FillTree(CTreeCtrl *tree,HNode *stopat,HTREEITEM parent) { if(stopat==NULL) return; } void HNode::FillTree(CTreeCtrl *tree,HTREEITEM parent,int level,int levelmax) { if(level>levelmax) return; Item=parent; if(!IsRoot() && level>0) { Item=AddItem(tree,parent); } for(int i=0;iFillTree(tree,Item,level+1); } } HTREEITEM HNode::AddItem(CTreeCtrl *tree,HTREEITEM parent) { HTREEITEM itm; if(Flag&HN_NOTFOUND || Flag&HN_LOOP) { CString con; if(Flag&HN_NOTFOUND) con+="(Not Found)"; if(Flag&HN_LOOP) con+="(Circular)"; itm=tree->InsertItem(Path+FName+con,parent); } else { itm=tree->InsertItem(Path+FName,parent); } tree->SetItemData(itm,(DWORD)this); return itm; } void HNode::FillReverseTree(CTreeCtrl *tree,HTREEITEM parent) { if(IsRoot()) return; HTREEITEM itm=AddItem(tree,parent); if(!Parent) return; Parent->FillReverseTree(tree,itm); int i; for(i=0;iParent) Clones[i]->Parent->FillReverseTree(tree,itm); if(IsCopy()) { if(Original->Parent) Original->Parent->FillReverseTree(tree,itm); for(int i=0;iClones.GetSize();i++) if(Original->Clones[i]!=this && Original->Clones[i]->Parent) Original->Clones[i]->Parent->FillReverseTree(tree,itm); } } void HNode::Copy(HNode *node) { ASSERT(node!=this); Destroy(); FName=node->FName; Path=node->Path; Flag=node->Flag; PathMan=node->PathMan; Original=node; node->Clones.Add(this); for(int i=0;iChildren.GetSize();i++) { Children.Add(node->Children[i]); } // VerifyNode(); } void HNode::Destroy() { if(!IsCopy()) { for(int i=0;iParent==this); Delete(node); Children[i]=NULL; } } Children.RemoveAll(); Clones.RemoveAll(); FName=""; Path=""; Flag=0; Original=NULL; PathMan=NULL; } DWORD HNode::NodeCount() { int sum=1; for(int i=0;iNodeCount(); } return sum; } DWORD HNode::TreeSize() { int sum=sizeof(HNode)+Children.GetSize()*sizeof(HNode *)+FName.GetLength()+Path.GetLength(); if(!IsCopy()) { for(int i=0;iTreeSize(); } } return sum; } HNode *HNode::AddChild(HNode *child) { ASSERT(child!=NULL); ASSERT(child->Parent==NULL); Children.Add(child); child->Parent=this; child->PathMan=PathMan; return child; } void HNode::VerifyNode() { ASSERT(this); for(int i=0;iParent); ASSERT(Children[i]->Parent==this); Children[i]->VerifyNode(); } } void HNode::ParseDsp(const CString &fname,const CString &path) { FName=fname; Path=path; CString dspbuf; // CString path=Path.Left(Path.ReverseFind('\\')+1); bool res=SysGetFile(FName,Path,dspbuf); ASSERT(res); int start=0; start=dspbuf.Find("SOURCE="); CString sfname; while(start>=0) { start+=strlen("SOURCE="); int endl=dspbuf.Find('\x0D',start); if(endl>=0) { sfname=dspbuf.Mid(start,endl-start); if(sfname.Left(2)==".\\") sfname=sfname.Mid(2); if(!sfname.Right(4).CompareNoCase(".cpp") || !sfname.Right(2).CompareNoCase(".c")) AddLocalFile(sfname,Path); } start=dspbuf.Find("SOURCE=",start+1); } } HNode *HNode::Find(const CString fname,HNode *after,bool returnnext) { if(after==NULL) returnnext=true; if(!FName.CompareNoCase(fname)) { if(returnnext) return this; if(after==this) returnnext=true; } HNode *ret=NULL; for(int i=0;iFind(fname,after,returnnext); if(ret) return ret; } return NULL; } void HNode::DrillDownTo(CTreeCtrl *tree) { if(IsRoot()) { return; } else Parent->DrillDownTo(tree); int i; if(Item==NULL) // If I haven't been added { for(i=0;i>Parent->Children.GetSize();i++) // Add me and my siblings Parent->Children[i]->Item=Parent->Children[i]->AddItem(tree,Parent->Item); ASSERT(Item); } for(i=0;i>Children.GetSize();i++) // Add my children if(!Children[i]->Item) Children[i]->Item=Children[i]->AddItem(tree,Parent->Item); tree->Expand(Parent->Item,TVE_EXPAND); // Expand my parent } HNode::~HNode() { Destroy(); Parent=NULL; }