]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTConfiguration.cxx
code cleanup
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTConfiguration.cxx
1 // $Id$
2
3 /**************************************************************************
4  * This file is property of and copyright by the ALICE HLT Project        * 
5  * ALICE Experiment at CERN, All rights reserved.                         *
6  *                                                                        *
7  * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
8  *                  for The ALICE HLT Project.                            *
9  *                                                                        *
10  * Permission to use, copy, modify and distribute this software and its   *
11  * documentation strictly for non-commercial purposes is hereby granted   *
12  * without fee, provided that the above copyright notice appears in all   *
13  * copies and that both the copyright notice and this permission notice   *
14  * appear in the supporting documentation. The authors make no claims     *
15  * about the suitability of this software for any purpose. It is          *
16  * provided "as is" without express or implied warranty.                  *
17  **************************************************************************/
18
19 //  @file   AliHLTConfiguration.cxx
20 //  @author Matthias Richter
21 //  @date   2007
22 //  @brief  HLT configuration description for a single component.
23 //  @note   The class is used in Offline (AliRoot) context
24
25 // see header file for class documentation
26 // or
27 // refer to README to build package
28 // or
29 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
30
31 #if __GNUC__>= 3
32 using namespace std;
33 #endif
34
35 #include <cerrno>
36 #include "AliHLTConfiguration.h"
37 #include "AliHLTConfigurationHandler.h"
38 #include "AliHLTTask.h"
39 #include "AliHLTComponent.h"
40 #include "AliHLTComponentHandler.h"
41 #include <iostream>
42 #include <string>
43 #include "TList.h"
44
45 /** ROOT macro for the implementation of ROOT specific class methods */
46 ClassImp(AliHLTConfiguration)
47
48 AliHLTConfiguration::AliHLTConfiguration()
49   :
50   fID(""),
51   fComponent(""),
52   fStringSources(""),
53   fNofSources(-1),
54   fListSources(),
55   fListSrcElementIdx(-1),
56   fArguments(""),
57   fArgc(-1),
58   fArgv(NULL),
59   fBufferSize(-1)
60
61   // see header file for class documentation
62   // or
63   // refer to README to build package
64   // or
65   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
66 }
67
68 AliHLTConfiguration::AliHLTConfiguration(const char* id, const char* component, const char* sources,
69                                          const char* arguments, const char* bufsize)
70   :
71   fID(id),
72   fComponent(component),
73   fStringSources(sources),
74   fNofSources(-1),
75   fListSources(),
76   fListSrcElementIdx(-1),
77   fArguments(arguments),
78   fArgc(-1),
79   fArgv(NULL),
80   fBufferSize(-1)
81 {
82   // see header file for function documentation
83   if (bufsize) fBufferSize=ConvertSizeString(bufsize);
84   if (id && component) {
85     if (fgConfigurationHandler) {
86       fgConfigurationHandler->RegisterConfiguration(this);
87     } else {
88       HLTWarning("no configuration handler set, skip registration");
89     }
90   }
91 }
92
93 AliHLTConfiguration::AliHLTConfiguration(const AliHLTConfiguration& src)
94   :
95   TObject(),
96   AliHLTLogging(),
97   fID(src.fID),
98   fComponent(src.fComponent),
99   fStringSources(src.fStringSources),
100   fNofSources(-1),
101   fListSources(),
102   fListSrcElementIdx(-1),
103   fArguments(src.fArguments),
104   fArgc(-1),
105   fArgv(NULL),
106   fBufferSize(src.fBufferSize)
107
108   // see header file for function documentation
109 }
110
111 AliHLTConfiguration& AliHLTConfiguration::operator=(const AliHLTConfiguration& src)
112
113   // see header file for function documentation
114   if (this==&src) return *this;
115
116   fID=src.fID;
117   fComponent=src.fComponent;
118   fStringSources=src.fStringSources;
119   fNofSources=-1;
120   fArguments=src.fArguments;
121   fArgc=-1;
122   fArgv=NULL;
123   fBufferSize=src.fBufferSize;
124   return *this;
125 }
126
127 AliHLTConfiguration::~AliHLTConfiguration()
128 {
129   // see header file for function documentation
130   if (fgConfigurationHandler) {
131     if (fgConfigurationHandler->FindConfiguration(fID.Data())!=NULL) {
132       // remove the configuration from the handler if it exists
133       // but DO NOT remove the clone configuration
134       fgConfigurationHandler->RemoveConfiguration(this);
135     }
136   }
137   if (fArgv != NULL) {
138     if (fArgc>0) {
139       for (int i=0; i<fArgc; i++) {
140         delete[] fArgv[i];
141       }
142     }
143     delete[] fArgv;
144     fArgv=NULL;
145   }
146
147   vector<AliHLTConfiguration*>::iterator element=fListSources.begin();
148   while (element!=fListSources.end()) {
149     fListSources.erase(element);
150     element=fListSources.begin();
151   }
152 }
153
154 /* the global configuration handler which is used to automatically register the configuration
155  */
156 AliHLTConfigurationHandler* AliHLTConfiguration::fgConfigurationHandler=NULL;
157
158 int AliHLTConfiguration::GlobalInit(AliHLTConfigurationHandler* pHandler)
159 {
160   // see header file for function documentation
161   int iResult=0;
162   if (fgConfigurationHandler!=NULL && fgConfigurationHandler!=pHandler) {
163     fgConfigurationHandler->Logging(kHLTLogWarning, "AliHLTConfiguration::GlobalInit", HLT_DEFAULT_LOG_KEYWORD, "configuration handler already initialized, overriding object %p with %p", fgConfigurationHandler, pHandler);
164   }
165   fgConfigurationHandler=pHandler;
166   return iResult;
167 }
168
169 int AliHLTConfiguration::GlobalDeinit(AliHLTConfigurationHandler* pHandler)
170 {
171   // see header file for function documentation
172   int iResult=0;
173   if (fgConfigurationHandler!=NULL && fgConfigurationHandler!=pHandler) {
174     fgConfigurationHandler->Logging(kHLTLogWarning, "AliHLTConfiguration::GlobalDeinit", HLT_DEFAULT_LOG_KEYWORD, "handler %p is not set, skip ...", pHandler);
175     return -EBADF;
176   }
177   fgConfigurationHandler=NULL;
178   return iResult;
179 }
180
181 const char* AliHLTConfiguration::GetName() const 
182 {
183   // see header file for function documentation
184   if (!fID.IsNull())
185     return fID.Data();
186   return TObject::GetName();
187 }
188
189 AliHLTConfiguration* AliHLTConfiguration::GetSource(const char* id)
190 {
191   // see header file for function documentation
192   AliHLTConfiguration* pSrc=NULL;
193   if (id) {
194     // first check the current element
195     if (fListSrcElementIdx>=0 && fListSrcElementIdx<(int)fListSources.size() &&
196         strcmp(id, (fListSources[fListSrcElementIdx])->GetName())==0) {
197       pSrc=fListSources[fListSrcElementIdx];
198       } else {
199       // check the list
200
201       pSrc=GetFirstSource();
202       while (pSrc) {
203         if (strcmp(id, pSrc->GetName())==0)
204           break;
205         pSrc=GetNextSource();
206       }
207     }
208   }
209   return pSrc;
210 }
211
212 AliHLTConfiguration* AliHLTConfiguration::GetFirstSource() const
213 {
214   // see header file for function documentation
215   AliHLTConfiguration* pSrc=NULL;
216   if (fNofSources>0) {
217     const_cast<AliHLTConfiguration*>(this)->fListSrcElementIdx=-1;
218     pSrc=GetNextSource();
219   } 
220   return pSrc;
221 }
222
223 AliHLTConfiguration* AliHLTConfiguration::GetNextSource() const
224 {
225   // see header file for function documentation
226   AliHLTConfiguration* pSrc=NULL;
227   if (fNofSources>0) {
228     if (fListSrcElementIdx+1<(int)fListSources.size()) {
229       const_cast<AliHLTConfiguration*>(this)->fListSrcElementIdx++;
230       pSrc=fListSources[fListSrcElementIdx];
231     }
232   } 
233   return pSrc;
234 }
235
236 int AliHLTConfiguration::SourcesResolved() const
237 {
238   // see header file for function documentation
239   int iResult=0;
240   if (fNofSources>=0) {
241     iResult=fNofSources==(int)fListSources.size();
242   }
243   return iResult;
244 }
245
246 int AliHLTConfiguration::InvalidateSource(AliHLTConfiguration* pConf)
247 {
248   // see header file for function documentation
249   int iResult=0;
250   if (pConf) {
251     vector<AliHLTConfiguration*>::iterator element=fListSources.begin();
252     while (element!=fListSources.end()) {
253       if (*element==pConf) {
254         fListSources.erase(element);
255         fListSrcElementIdx=fListSources.size();
256         // there is no need to re-evaluate until there was a new configuration registered
257         // -> postpone the invalidation, its done in AliHLTConfigurationHandler::RegisterConfiguration
258         //InvalidateSources();
259         break;
260       }
261       element++;
262     }
263   } else {
264     iResult=-EINVAL;
265   }
266   return iResult;
267 }
268
269 void AliHLTConfiguration::PrintStatus() const
270 {
271   // see header file for function documentation
272   HLTLogKeyword("configuration status");
273   HLTMessage("status of configuration \"%s\" (%p)", GetName(), this);
274   if (!fComponent.IsNull()) HLTMessage("  - component: \"%s\"", fComponent.Data());
275   else HLTMessage("  - component string invalid");
276   if (!fStringSources.IsNull()) HLTMessage("  - sources: \"%s\"", fStringSources.Data());
277   else HLTMessage("  - no sources");
278   if (SourcesResolved()!=1)
279     HLTMessage("    there are unresolved sources");
280   AliHLTConfiguration* pSrc=GetFirstSource();
281   while (pSrc) {
282     HLTMessage("    source \"%s\" (%p) resolved", pSrc->GetName(), pSrc);
283     pSrc=GetNextSource();
284   }
285 }
286
287 void AliHLTConfiguration::Print(const char* option) const
288 {
289   // print information
290   if (option && strcmp(option, "status")==0) {
291     PrintStatus();
292     return;
293   }
294   HLTLogKeyword("configuration");
295   HLTMessage("configuration %s: component %s, sources %s, arguments %s",
296              GetName(),
297              GetComponentID(),
298              GetSourceSettings(),
299              GetArgumentSettings()
300              );
301 }
302
303 int AliHLTConfiguration::GetArguments(const char*** pArgv) const
304 {
305   // see header file for function documentation
306   int iResult=0;
307   if (pArgv) {
308     if (fArgc==-1) {
309       if ((iResult=const_cast<AliHLTConfiguration*>(this)->ExtractArguments())<0) {
310         HLTError("error extracting arguments for configuration %s", GetName());
311       }
312     } else if (fArgc<0) {
313       HLTError("previous argument extraction failed");
314     }
315     //HLTDebug("%s fArgc %d", GetName(), fArgc);
316     iResult=fArgc;
317     *pArgv=(const char**)fArgv;
318   } else {
319     HLTError("invalid parameter");
320     iResult=-EINVAL;
321   }
322   return iResult;
323 }
324
325
326 int AliHLTConfiguration::ExtractSources()
327 {
328   // see header file for function documentation
329   int iResult=0;
330   fNofSources=0; // indicates that the function was called, there are either n or 0 sources
331   fListSources.clear();
332   if (!fgConfigurationHandler) {
333     HLTError("global configuration handler not initialized, can not resolve sources");
334     return -EFAULT;
335   }
336   if (!fStringSources.IsNull()) {
337     vector<char*> tgtList;
338     if ((iResult=InterpreteString(fStringSources.Data(), tgtList))>=0) {
339       fNofSources=tgtList.size();
340       vector<char*>::iterator element=tgtList.begin();
341       while ((element=tgtList.begin())!=tgtList.end()) {
342           AliHLTConfiguration* pConf=fgConfigurationHandler->FindConfiguration(*element);
343           if (pConf) {
344             //HLTDebug("configuration %s (%p): source \"%s\" (%p) inserted", GetName(), this, pConf->GetName(), pConf);
345             fListSources.push_back(pConf);
346           } else {
347             HLTError("can not find source \"%s\"", (*element));
348             iResult=-ENOENT;
349           }
350         delete[] (*element);
351         tgtList.erase(element);
352       }
353     }
354   }
355   fListSrcElementIdx=-1;
356   return iResult<0?iResult:SourcesResolved();
357 }
358
359 int AliHLTConfiguration::ExtractArguments()
360 {
361   // see header file for function documentation
362   int iResult=0;
363   if (!fArguments.IsNull()) {
364     vector<char*> tgtList;
365     if ((iResult=InterpreteString(fArguments, tgtList))>=0) {
366       fArgc=tgtList.size();
367       //HLTDebug("configuration %s: extracted %d arguments from \"%s\"", GetName(), fArgc, fArguments);
368       if (fArgc>0) {
369         fArgv = new char*[fArgc];
370         if (fArgv) {
371           vector<char*>::iterator element=tgtList.begin();
372           int i=0;
373           while (element!=tgtList.end()) {
374             //HLTDebug("assign arguments %d (%s)", i, *element);
375             fArgv[i++]=(*element);
376             element++;
377           }
378         } else {
379           iResult=-ENOMEM;
380         }
381       }
382     }
383   } else {
384     // there are zero arguments
385     fArgc=0;
386   }
387   if (iResult<0) fArgc=iResult;
388   return iResult;
389 }
390
391 int AliHLTConfiguration::InterpreteString(const char* arg, vector<char*>& argList)
392 {
393   // see header file for function documentation
394   int iResult=0;
395   if (arg) {
396     //HLTDebug("interprete \"%s\"", arg);
397     int i=0;
398     int prec=-1;
399     int bQuote=0;
400     do {
401       //HLTDebug("%d %x", i, arg[i]);
402       if (arg[i]=='\'' && bQuote==0) {
403         bQuote=1;
404       } else if (arg[i]==0 || 
405                  (arg[i]==' ' && bQuote==0) ||
406                  (arg[i]=='\'' && bQuote==1)) {
407         bQuote=0;
408         if (prec>=0) {
409           char* pEntry= new char[i-prec+1];
410           if (pEntry) {
411             strncpy(pEntry, &arg[prec], i-prec);
412             pEntry[i-prec]=0; // terminate string
413             //HLTDebug("create string \"%s\", insert at %d", pEntry, argList.size());
414             argList.push_back(pEntry);
415           } else 
416             iResult=-ENOMEM;
417           prec=-1;
418         }
419       } else if (prec==-1) prec=i;
420     } while (arg[i++]!=0 && iResult>=0); 
421   } else {
422     iResult=-EINVAL;
423   }
424   return iResult;
425 }
426
427 int AliHLTConfiguration::ConvertSizeString(const char* strSize) const
428 {
429   // see header file for function documentation
430   int size=0;
431   if (!strSize) return -1;
432
433   char* endptr=NULL;
434   size=strtol(strSize, &endptr, 10);
435   if (size>=0) {
436     if (endptr) {
437       if (endptr==strSize) {
438         HLTWarning("ignoring unrecognized buffer size '%s'", strSize);
439         size=-1;
440       } else if (*endptr==0) {
441         // no unit specifier
442       } else if (*endptr=='k') {
443         size*=1014;
444       } else if (*endptr=='M') {
445         size*=1024*1024;
446       } else {
447         HLTWarning("ignoring buffer size of unknown unit '%c'", endptr[0]);
448       }
449     } else {
450       HLTWarning("ignoring negative buffer size specifier '%s'", strSize);
451       size=-1;
452     }
453   }
454   return size;
455 }
456
457 int AliHLTConfiguration::FollowDependency(const char* id, TList* pTgtList)
458 {
459   // see header file for function documentation
460   int iResult=0;
461   if (id) {
462     AliHLTConfiguration* pDep=NULL;
463     if ((pDep=GetSource(id))!=NULL) {
464       if (pTgtList) pTgtList->Add(pDep);
465       iResult++;
466     } else {
467       pDep=GetFirstSource();
468       while (pDep && iResult==0) {
469         if ((iResult=pDep->FollowDependency(id, pTgtList))>0) {
470           if (pTgtList) pTgtList->AddFirst(pDep);
471           iResult++;
472         }
473         pDep=GetNextSource();
474       }
475     }
476   } else {
477     iResult=-EINVAL;
478   }
479   return iResult;
480 }
481
482