3 ScanTree::ScanTree(StringList *FileMasks,int Recurse,bool GetLinks,int GetDirs)
5 ScanTree::FileMasks=FileMasks;
6 ScanTree::Recurse=Recurse;
7 ScanTree::GetLinks=GetLinks;
8 ScanTree::GetDirs=GetDirs;
13 memset(FindStack,0,sizeof(FindStack));
24 for (int I=Depth;I>=0;I--)
25 if (FindStack[I]!=NULL)
30 int ScanTree::GetNext(FindData *FindData)
38 if ((*CurMask==0 || (FastFindFile && Depth==0)) && !PrepareMasks())
40 FindCode=FindProc(FindData);
41 if (FindCode==SCAN_ERROR)
46 if (FindCode==SCAN_NEXT)
48 if (FindCode==SCAN_SUCCESS && FindData->IsDir && GetDirs==SCAN_SKIPDIRS)
50 if (FindCode==SCAN_DONE && PrepareMasks())
58 bool ScanTree::PrepareMasks()
60 if (!FileMasks->GetString(CurMask,CurMaskW,sizeof(CurMask)))
63 UnixSlashToDos(CurMask);
65 char *Name=PointToName(CurMask);
67 strcat(CurMask,MASKALL);
68 if (Name[0]=='.' && (Name[1]==0 || (Name[1]=='.' && Name[2]==0)))
71 strcat(CurMask,MASKALL);
73 SpecPathLength=Name-CurMask;
74 // if (SpecPathLength>1)
77 bool WideName=(*CurMaskW!=0);
81 wchar *NameW=PointToName(CurMaskW);
83 strcatw(CurMaskW,MASKALLW);
84 if (NameW[0]=='.' && (NameW[1]==0 || (NameW[1]=='.' && NameW[2]==0)))
86 AddEndSlash(CurMaskW);
87 strcatw(CurMaskW,MASKALLW);
89 SpecPathLengthW=NameW-CurMaskW;
94 CharToWide(CurMask,WideMask);
95 SpecPathLengthW=PointToName(WideMask)-WideMask;
99 strcpy(OrigCurMask,CurMask);
100 strcpyw(OrigCurMaskW,CurMaskW);
106 int ScanTree::FindProc(FindData *FindData)
111 if (FindStack[Depth]==NULL)
113 bool Wildcards=IsWildcard(CurMask,CurMaskW);
114 bool FindCode=!Wildcards && FindFile::FastFind(CurMask,CurMaskW,FindData,GetLinks);
115 bool IsDir=FindCode && FindData->IsDir;
116 bool SearchAll=!IsDir && (Depth>0 || Recurse==RECURSE_ALWAYS || (Wildcards && Recurse==RECURSE_WILDCARDS));
118 SearchAllInRoot=SearchAll;
119 if (SearchAll || Wildcards)
121 FindStack[Depth]=new FindFile;
123 strcpy(SearchMask,CurMask);
125 strcpy(PointToName(SearchMask),MASKALL);
126 FindStack[Depth]->SetMask(SearchMask);
129 wchar SearchMaskW[NM];
130 strcpyw(SearchMaskW,CurMaskW);
132 strcpyw(PointToName(SearchMaskW),MASKALLW);
133 FindStack[Depth]->SetMaskW(SearchMaskW);
141 if (Cmd!=NULL && Cmd->ExclCheck(CurMask,true))
143 ErrHandler.OpenErrorMsg(ErrArcName,CurMask);
144 return(FindData->Error ? SCAN_ERROR:SCAN_NEXT);
149 if (!FastFindFile && !FindStack[Depth]->Next(FindData,GetLinks))
151 bool Error=FindData->Error;
154 if (Error && strstr(CurMask,"System Volume Information\\")!=NULL)
158 if (Cmd!=NULL && Cmd->ExclCheck(CurMask,true))
164 Log(NULL,St(MScanError),CurMask);
173 delete FindStack[Depth];
174 FindStack[Depth--]=NULL;
175 while (Depth>=0 && FindStack[Depth]==NULL)
183 char *Slash=strrchrd(CurMask,CPATHDIVIDER);
188 if (Depth<SetAllMaskDepth)
189 strcpy(Mask+1,PointToName(OrigCurMask));
191 strcpy(DirName,CurMask);
192 char *PrevSlash=strrchrd(CurMask,CPATHDIVIDER);
194 strcpy(CurMask,Mask+1);
196 strcpy(PrevSlash,Mask);
201 wchar *Slash=strrchrw(CurMaskW,CPATHDIVIDER);
207 strcpyw(DirNameW,CurMaskW);
208 wchar *PrevSlash=strrchrw(CurMaskW,CPATHDIVIDER);
210 strcpyw(CurMaskW,Mask+1);
212 strcpyw(PrevSlash,Mask);
215 if (LowAscii(CurMaskW))
219 if (GetDirs==SCAN_GETDIRSTWICE &&
220 FindFile::FastFind(DirName,DirNameW,FindData,GetLinks) && FindData->IsDir)
221 return(Error ? SCAN_ERROR:SCAN_SUCCESS);
222 return(Error ? SCAN_ERROR:SCAN_NEXT);
227 if (!FastFindFile && Depth==0 && !SearchAllInRoot)
228 return(GetDirs==SCAN_GETCURDIRS ? SCAN_SUCCESS:SCAN_NEXT);
230 // if (GetDirs==SCAN_GETCURDIRS && Depth==0 && !SearchAllInRoot)
231 // return(SCAN_SUCCESS);
234 bool MaskAll=FastFindFile;
236 strcpy(Mask,MaskAll ? MASKALL:PointToName(CurMask));
237 strcpy(CurMask,FindData->Name);
239 if (strlen(CurMask)+strlen(Mask)+1>=NM || Depth>=MAXSCANDEPTH-1)
242 Log(NULL,"\n%s%c%s",CurMask,CPATHDIVIDER,Mask);
243 Log(NULL,St(MPathTooLong));
248 AddEndSlash(CurMask);
249 strcat(CurMask,Mask);
251 if (*CurMaskW && *FindData->NameW==0)
252 CharToWide(FindData->Name,FindData->NameW);
253 if (*FindData->NameW!=0)
257 strcpyw(Mask,MASKALLW);
260 strcpyw(Mask,PointToName(CurMaskW));
262 CharToWide(PointToName(CurMask),Mask);
263 strcpyw(CurMaskW,FindData->NameW);
264 AddEndSlash(CurMaskW);
265 strcatw(CurMaskW,Mask);
269 SetAllMaskDepth=Depth;
271 if (!FastFindFile && !CmpName(CurMask,FindData->Name,MATCH_NAMES))
273 return(SCAN_SUCCESS);