]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTConfiguration.cxx
adding common functionality for the magnetic field to the component interface
[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   
22     @brief  Implementation of HLT configurations.
23 */
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   fListSrcElement(),
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   fListSrcElement=fListSources.begin();
68 }
69
70 AliHLTConfiguration::AliHLTConfiguration(const char* id, const char* component, const char* sources,
71                                          const char* arguments, const char* bufsize)
72   :
73   fID(id),
74   fComponent(component),
75   fStringSources(sources),
76   fNofSources(-1),
77   fListSources(),
78   fListSrcElement(),
79   fArguments(arguments),
80   fArgc(-1),
81   fArgv(NULL),
82   fBufferSize(-1)
83 {
84   // see header file for function documentation
85   if (bufsize) fBufferSize=ConvertSizeString(bufsize);
86   fListSrcElement=fListSources.begin();
87   if (id && component) {
88     if (fgConfigurationHandler) {
89       fgConfigurationHandler->RegisterConfiguration(this);
90     } else {
91       HLTError("no configuration handler set, abort registration");
92     }
93   }
94 }
95
96 AliHLTConfiguration::AliHLTConfiguration(const AliHLTConfiguration& src)
97   :
98   TObject(),
99   AliHLTLogging(),
100   fID(src.fID),
101   fComponent(src.fComponent),
102   fStringSources(src.fStringSources),
103   fNofSources(-1),
104   fListSources(),
105   fListSrcElement(),
106   fArguments(src.fArguments),
107   fArgc(-1),
108   fArgv(NULL),
109   fBufferSize(src.fBufferSize)
110
111   // see header file for function documentation
112   fListSrcElement=fListSources.begin();
113 }
114
115 AliHLTConfiguration& AliHLTConfiguration::operator=(const AliHLTConfiguration& src)
116
117   // see header file for function documentation
118   fID=src.fID;
119   fComponent=src.fComponent;
120   fStringSources=src.fStringSources;
121   fNofSources=-1;
122   fArguments=src.fArguments;
123   fArgc=-1;
124   fArgv=NULL;
125   fBufferSize=src.fBufferSize;
126   return *this;
127 }
128
129 AliHLTConfiguration::~AliHLTConfiguration()
130 {
131   // see header file for function documentation
132   if (fgConfigurationHandler) {
133     if (fgConfigurationHandler->FindConfiguration(fID.Data())!=NULL) {
134       // remove the configuration from the handler if it exists
135       // but DO NOT remove the clone configuration
136       fgConfigurationHandler->RemoveConfiguration(this);
137     }
138   }
139   if (fArgv != NULL) {
140     if (fArgc>0) {
141       for (int i=0; i<fArgc; i++) {
142         delete[] fArgv[i];
143       }
144     }
145     delete[] fArgv;
146     fArgv=NULL;
147   }
148
149   vector<AliHLTConfiguration*>::iterator element=fListSources.begin();
150   while (element!=fListSources.end()) {
151     fListSources.erase(element);
152     element=fListSources.begin();
153   }
154 }
155
156 /* the global configuration handler which is used to automatically register the configuration
157  */
158 AliHLTConfigurationHandler* AliHLTConfiguration::fgConfigurationHandler=NULL;
159
160 int AliHLTConfiguration::GlobalInit(AliHLTConfigurationHandler* pHandler)
161 {
162   // see header file for function documentation
163   int iResult=0;
164   if (fgConfigurationHandler!=NULL && fgConfigurationHandler!=pHandler) {
165     fgConfigurationHandler->Logging(kHLTLogWarning, "AliHLTConfiguration::GlobalInit", HLT_DEFAULT_LOG_KEYWORD, "configuration handler already initialized, overriding object %p with %p", fgConfigurationHandler, pHandler);
166   }
167   fgConfigurationHandler=pHandler;
168   return iResult;
169 }
170
171 int AliHLTConfiguration::GlobalDeinit(AliHLTConfigurationHandler* pHandler)
172 {
173   // see header file for function documentation
174   int iResult=0;
175   if (fgConfigurationHandler!=NULL && fgConfigurationHandler!=pHandler) {
176     fgConfigurationHandler->Logging(kHLTLogWarning, "AliHLTConfiguration::GlobalDeinit", HLT_DEFAULT_LOG_KEYWORD, "handler %p is not set, skip ...", pHandler);
177     return -EBADF;
178   }
179   fgConfigurationHandler=NULL;
180   return iResult;
181 }
182
183 const char* AliHLTConfiguration::GetName() const 
184 {
185   // see header file for function documentation
186   if (!fID.IsNull())
187     return fID.Data();
188   return TObject::GetName();
189 }
190
191 AliHLTConfiguration* AliHLTConfiguration::GetSource(const char* id)
192 {
193   // see header file for function documentation
194   AliHLTConfiguration* pSrc=NULL;
195   if (id) {
196     // first check the current element
197     if (fListSrcElement!=fListSources.end() && strcmp(id, (*fListSrcElement)->GetName())==0) {
198       pSrc=*fListSrcElement;
199       } else {
200       // check the list
201
202       pSrc=GetFirstSource();
203       while (pSrc) {
204         if (strcmp(id, pSrc->GetName())==0)
205           break;
206         pSrc=GetNextSource();
207       }
208     }
209   }
210   return pSrc;
211 }
212
213 AliHLTConfiguration* AliHLTConfiguration::GetFirstSource()
214 {
215   // see header file for function documentation
216   AliHLTConfiguration* pSrc=NULL;
217   if (fNofSources>=0 || ExtractSources()>=0) {
218     fListSrcElement=fListSources.begin();
219     if (fListSrcElement!=fListSources.end()) pSrc=*fListSrcElement;
220   } 
221   return pSrc;
222 }
223
224 AliHLTConfiguration* AliHLTConfiguration::GetNextSource()
225 {
226   // see header file for function documentation
227   AliHLTConfiguration* pSrc=NULL;
228   if (fNofSources>0) {
229     if (fListSrcElement!=fListSources.end() && (++fListSrcElement)!=fListSources.end()) 
230       pSrc=*fListSrcElement;
231   } 
232   return pSrc;
233 }
234
235 int AliHLTConfiguration::SourcesResolved(int bAuto) 
236 {
237   // see header file for function documentation
238   int iResult=0;
239   if (fNofSources>=0 || (bAuto && (iResult=ExtractSources()))>=0) {
240     //HLTDebug("fNofSources=%d", fNofSources);
241     //HLTDebug("list size = %d", fListSources.size());
242     iResult=fNofSources==(int)fListSources.size();
243   }
244   return iResult;
245 }
246
247 int AliHLTConfiguration::InvalidateSource(AliHLTConfiguration* pConf)
248 {
249   // see header file for function documentation
250   int iResult=0;
251   if (pConf) {
252     vector<AliHLTConfiguration*>::iterator element=fListSources.begin();
253     while (element!=fListSources.end()) {
254       if (*element==pConf) {
255         fListSources.erase(element);
256         fListSrcElement=fListSources.end();
257         // there is no need to re-evaluate until there was a new configuration registered
258         // -> postpone the invalidation, its done in AliHLTConfigurationHandler::RegisterConfiguration
259         //InvalidateSources();
260         break;
261       }
262       element++;
263     }
264   } else {
265     iResult=-EINVAL;
266   }
267   return iResult;
268 }
269
270 void AliHLTConfiguration::PrintStatus()
271 {
272   // see header file for function documentation
273   HLTLogKeyword("configuration status");
274   HLTMessage("status of configuration \"%s\" (%p)", GetName(), this);
275   if (!fComponent.IsNull()) HLTMessage("  - component: \"%s\"", fComponent.Data());
276   else HLTMessage("  - component string invalid");
277   if (!fStringSources.IsNull()) HLTMessage("  - sources: \"%s\"", fStringSources.Data());
278   else HLTMessage("  - no sources");
279   if (SourcesResolved(1)<=0)
280     HLTMessage("    there are unresolved sources");
281   AliHLTConfiguration* pSrc=GetFirstSource();
282   while (pSrc) {
283     HLTMessage("    source \"%s\" (%p) resolved", pSrc->GetName(), pSrc);
284     pSrc=GetNextSource();
285   }
286 }
287
288 int AliHLTConfiguration::GetArguments(const char*** pArgv)
289 {
290   // see header file for function documentation
291   int iResult=0;
292   if (pArgv) {
293     if (fArgc==-1) {
294       if ((iResult=ExtractArguments())<0) {
295         HLTError("error extracting arguments for configuration %s", GetName());
296         fArgc=-EINVAL;
297       }
298     } else if (fArgc<0) {
299       HLTError("previous argument extraction failed");
300     }
301     //HLTDebug("%s fArgc %d", GetName(), fArgc);
302     iResult=fArgc;
303     *pArgv=(const char**)fArgv;
304   } else {
305     HLTError("invalid parameter");
306     iResult=-EINVAL;
307   }
308   return iResult;
309 }
310
311
312 int AliHLTConfiguration::ExtractSources()
313 {
314   // see header file for function documentation
315   int iResult=0;
316   fNofSources=0;
317   if (!fStringSources.IsNull()) {
318     vector<char*> tgtList;
319     fListSources.clear();
320     if ((iResult=InterpreteString(fStringSources.Data(), tgtList))>=0) {
321       fNofSources=tgtList.size();
322       vector<char*>::iterator element=tgtList.begin();
323       while ((element=tgtList.begin())!=tgtList.end()) {
324         if (fgConfigurationHandler) {
325           AliHLTConfiguration* pConf=fgConfigurationHandler->FindConfiguration(*element);
326           if (pConf) {
327             //HLTDebug("configuration %s (%p): source \"%s\" (%p) inserted", GetName(), this, pConf->GetName(), pConf);
328             fListSources.push_back(pConf);
329           } else {
330             HLTError("can not find source \"%s\"", (*element));
331             iResult=-ENOENT;
332           }
333         } else if (iResult>=0) {
334           iResult=-EFAULT;
335           HLTFatal("global configuration handler not initialized, can not resolve sources");
336         }
337         delete[] (*element);
338         tgtList.erase(element);
339       }
340       fListSrcElement=fListSources.begin();
341     }
342   }
343   return iResult;
344 }
345
346 int AliHLTConfiguration::ExtractArguments()
347 {
348   // see header file for function documentation
349   int iResult=0;
350   if (!fArguments.IsNull()) {
351     vector<char*> tgtList;
352     if ((iResult=InterpreteString(fArguments, tgtList))>=0) {
353       fArgc=tgtList.size();
354       //HLTDebug("configuration %s: extracted %d arguments from \"%s\"", GetName(), fArgc, fArguments);
355       if (fArgc>0) {
356         fArgv = new char*[fArgc];
357         if (fArgv) {
358           vector<char*>::iterator element=tgtList.begin();
359           int i=0;
360           while (element!=tgtList.end()) {
361             //HLTDebug("assign arguments %d (%s)", i, *element);
362             fArgv[i++]=(*element);
363             element++;
364           }
365         } else {
366           iResult=-ENOMEM;
367         }
368       }
369     }
370   } else {
371     // there are zero arguments
372     fArgc=0;
373   }
374   return iResult;
375 }
376
377 int AliHLTConfiguration::InterpreteString(const char* arg, vector<char*>& argList)
378 {
379   // see header file for function documentation
380   int iResult=0;
381   if (arg) {
382     //HLTDebug("interprete \"%s\"", arg);
383     int i=0;
384     int prec=-1;
385     int bQuote=0;
386     do {
387       //HLTDebug("%d %x", i, arg[i]);
388       if (arg[i]=='\'' && bQuote==0) {
389         bQuote=1;
390       } else if (arg[i]==0 || 
391                  (arg[i]==' ' && bQuote==0) ||
392                  (arg[i]=='\'' && bQuote==1)) {
393         bQuote=0;
394         if (prec>=0) {
395           char* pEntry= new char[i-prec+1];
396           if (pEntry) {
397             strncpy(pEntry, &arg[prec], i-prec);
398             pEntry[i-prec]=0; // terminate string
399             //HLTDebug("create string \"%s\", insert at %d", pEntry, argList.size());
400             argList.push_back(pEntry);
401           } else 
402             iResult=-ENOMEM;
403           prec=-1;
404         }
405       } else if (prec==-1) prec=i;
406     } while (arg[i++]!=0 && iResult>=0); 
407   } else {
408     iResult=-EINVAL;
409   }
410   return iResult;
411 }
412
413 int AliHLTConfiguration::ConvertSizeString(const char* strSize) const
414 {
415   // see header file for function documentation
416   int size=0;
417   if (!strSize) return -1;
418
419   char* endptr=NULL;
420   size=strtol(strSize, &endptr, 10);
421   if (size>=0) {
422     if (endptr) {
423       if (endptr==strSize) {
424         HLTWarning("ignoring unrecognized buffer size '%s'", strSize);
425         size=-1;
426       } else if (*endptr==0) {
427         // no unit specifier
428       } else if (*endptr=='k') {
429         size*=1014;
430       } else if (*endptr=='M') {
431         size*=1024*1024;
432       } else {
433         HLTWarning("ignoring buffer size of unknown unit '%c'", endptr[0]);
434       }
435     } else {
436       HLTWarning("ignoring negative buffer size specifier '%s'", strSize);
437       size=-1;
438     }
439   }
440   return size;
441 }
442
443 int AliHLTConfiguration::FollowDependency(const char* id, TList* pTgtList)
444 {
445   // see header file for function documentation
446   int iResult=0;
447   if (id) {
448     AliHLTConfiguration* pDep=NULL;
449     if ((pDep=GetSource(id))!=NULL) {
450       if (pTgtList) pTgtList->Add(pDep);
451       iResult++;
452     } else {
453       pDep=GetFirstSource();
454       while (pDep && iResult==0) {
455         if ((iResult=pDep->FollowDependency(id, pTgtList))>0) {
456           if (pTgtList) pTgtList->AddFirst(pDep);
457           iResult++;
458         }
459         pDep=GetNextSource();
460       }
461     }
462   } else {
463     iResult=-EINVAL;
464   }
465   return iResult;
466 }
467
468