StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
TDirIter.cxx
1 /***************************************************************************
2  *
3  * $Id: TDirIter.cxx,v 1.14 2009/10/06 21:01:30 fine Exp $
4  *
5  ***************************************************************************
6  *
7  * Description:
8  *
9  ***************************************************************************
10  **************************************************************************/
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <assert.h>
15 #include "TSystem.h"
16 #include "TObjArray.h"
17 #include "TError.h"
18 
19 #include "TDirIter.h"
20 
21 
22 //ClassImp(TDirIter)
23 //______________________________________________________________________________
24 TDirIter::TDirIter(const char *path,Int_t maxlev):fRegx("",0)
25 {
26  fArr = new TObjArray;
27  Reset(path,maxlev);
28 }
29 //______________________________________________________________________________
30 TDirIter::~TDirIter()
31 {
32  fArr->Delete();
33  delete fArr;
34  fArr=0;
35 }
36 //______________________________________________________________________________
37 void TDirIter::Reset(const char *path,Int_t maxlev)
38 {
39  fIter = -1;
40  fArr->Delete();
41  fFull = "";
42  fMaxLev = maxlev;
43  if (*path == '@') { //read path's from file
44  FILE *in = fopen(path+1,"r");
45  if (!in) {
46  fprintf(stderr,"*** TDirIter::Reset failed to open %s ***\n",path+1);
47  fSele = -2;
48  return;
49  }
50 
51  char buf[1024];
52  while ( fgets(buf,1024,in) ) {
53  if (*buf == '!') continue; //commented
54  if (*buf == '#') continue; //commented
55 
56  char *c = strchr(buf,' ');
57  if (c){
58  // If space, take first part but don't forget to restore \n
59  *c= '\0';
60  fFull += buf;
61  fFull += "\n";
62  } else {
63  fFull += buf;
64  }
65  }
66  fclose(in);
67 
68  } else {
69  fFull = path;
70 
71  }
72  // printf("DEBUG --> [%s] [%s]\n",path,fFull.Data());
73 
74  fSkip = strspn(fFull.Data()," \t\n");
75  ResetQQ(fFull.Data()+fSkip);
76 }
77 //______________________________________________________________________________
78 void TDirIter::ResetQQ(const char *path)
79 {
80  TString machine("root://");
81  machine += gSystem->HostName();
82  machine += "/";
83  fLevel = 0; fState = 1; fSele=0; fTop = 0;
84  fMaxLevQQ = fMaxLev;
85  int n = strcspn(path," \t\n");
86  TString myPath; myPath.Insert(0,path,n);
87  gSystem->ExpandPathName(myPath);
88 
89  fEntrStk[0]=0;
90  const char *p = myPath.Data();
91  if (*p == '^') p++;
92  fFile = p;
93  if (fFile.BeginsWith(machine)) {
94  fFile.ReplaceAll(machine,"");
95  } else {
96  fFile.ReplaceAll(".gov//",".gov:1095//");
97  }
98  const char *c,*f=fFile.Data();
99  c = strpbrk(f,"*#?[]\\");
100  if (c) {
101  fSele=1;fFile.Remove(c-f,9999);
102  int s = fFile.Last('/');
103  if (s>0) {fFile.Remove(s,9999);}
104  else {fFile = "";}
105  }
106  if (fFile.Length()==0) f = ".";
107  if (fSele==0) {
108  Long_t flags = 0, id = 0, modtime = 0; Long64_t size=1;
109  int noexi = 0;
110  if (! strstr(f,"://"))
111  noexi = gSystem->GetPathInfo(f,&id,&size,&flags,&modtime);
112  if (noexi) {
113  fSele = -2;
114  Warning("TDirIter","*** File %s does not exist ***",f);}
115  else if (size==0) {
116  fSele = -2;
117  Warning("TDirIter","*** File %s is empty ***",f);}
118  else if ((flags&2)==0) {
119  fSele = -1;
120  Warning("TDirIter","*** File %s is special (like socket) ***",f);}
121  }
122 
123  fTop = fFile.Length();
124  if (myPath[0]=='^') fTop = 0;
125  TString QWE = MakeWild(myPath.Data()+fTop);
126  fRegx=TRegexp(QWE);
127 
128  p = myPath.Data();
129  int lP = myPath.Length();
130  if (lP && *p!='^' && strstr(p,"#")==0) {//calculate maxlevQQ
131  fMaxLevQQ=1;
132  for(int i=fTop+1;i<lP;i++) { if (p[i]=='/') fMaxLevQQ++; } }
133 }
134 //______________________________________________________________________________
135 const char *TDirIter::NextFile()
136 {
137  if (fIter == -1) {
138  const char *name=0;
139  while((name=NextFileQ())) {fArr->Add(new TNamed(name,""));}
140  fArr->Sort();
141  }
142  fIter++;
143  if (fIter > fArr->GetLast()) return 0;
144  return fArr->At(fIter)->GetName();
145 }
146 
147 //______________________________________________________________________________
148 const char *TDirIter::NextFileQ()
149 {
150 
151  const char *name = NextFileQQ();
152  if (name) return name;
153  const char *full = fFull.Data();
154  if (full[fSkip]==0) return 0;
155  fSkip += strcspn(full+fSkip," \t\n");
156  if (full[fSkip]==0) return 0;
157  fSkip += strspn(full+fSkip," \t\n");
158  if (full[fSkip]==0) return 0;
159 
160  ResetQQ(full+fSkip);
161  return NextFileQ();
162 }
163 //______________________________________________________________________________
164 const char *TDirIter::NextFileQQ()
165 {
166  if (fSele == -2) return 0;
167  if (fSele == -1) {fSele = -2; return fFile.Data();}
168  while(2002) {
169  if (fState && fLevel < fMaxLevQQ) { //Last name was directory
170  fLevel++; fState=0;
171  const char *f = fFile.Data();
172  if (*f==0) f=".";
173  fEntrStk[fLevel] = gSystem->OpenDirectory(f);
174  fLengStk[fLevel] = fFile.Length();
175  }
176 
177  const char *name;
178  while ((name = gSystem->GetDirEntry(fEntrStk[fLevel])))
179  {
180  if (strcmp("." ,name)==0) continue;
181  if (strcmp("..",name)==0) continue;
182  break;
183  }
184  if (name==0) {
185  gSystem->FreeDirectory(fEntrStk[fLevel]);
186  if (fLevel<=0) return 0;
187  fLevel--; fState=0;
188  return NextFileQ();
189  }
190 
191  fFile.Remove(fLengStk[fLevel],999);
192  if (fFile.Length()) fFile += "/"; fFile += name;
193  Long_t flags=0; fState=0;
194  Long_t id = 0, modtime = 0;Long64_t size=0;
195  if (strstr(fFile.Data(),"://")==0)
196  gSystem->GetPathInfo(fFile.Data(),&id,&size,&flags,&modtime);
197  if (flags & 2) fState=1;
198  if (fSele==0) break;
199  int len;
200  TString qwe(fFile.Data()+fTop);
201  if (fRegx.Index(qwe,&len) >=0) break;
202 
203  }
204  return fFile.Data();
205 }
206 //______________________________________________________________________________
207 TString TDirIter::MakeWild(const char *re)
208 {
209  TString ts;
210  if (re[0]=='^') { ts = re; return ts;}
211 
212  for (int i=0;re[i];i++)
213  {
214  if (i == 0) {ts+="^" ;}
215  if (re[i]=='*') {ts+="[a-zA-Z0-9_\\.,-= ]*"; continue;}
216  if (re[i]=='#') {ts+=".*"; continue;}
217  if (re[i] == '.') {ts+="\\."; continue;}
218  ts += re[i];
219  }
220  ts += "$";
221  return ts;
222 }
223 
224 
225 
226 
227 
228 
229